package com.platform.api;

import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.platform.annotation.APPLoginUser;
import com.platform.annotation.IgnoreAuth;
import com.platform.annotation.LoginUser;
import com.platform.cache.J2CacheUtils;
import com.platform.constant.ApiConstant;
import com.platform.dao.*;
import com.platform.entity.*;
import com.platform.entity.activity.ActivitySign;
import com.platform.oss.OSSFactory;
import com.platform.service.*;
import com.platform.util.*;
import com.platform.util.wechat.*;
import com.platform.utils.Base64;
import com.platform.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 健国e商微信公众号接口
 * @author hqb
 * @date 2021-02-13 23:22
 */
@Api(tags = "1健国e商微信公众号接口")
@RestController
@RequestMapping("/api/mp")
@Slf4j
public class ApiMpController extends ApiBaseAction {

    @Value("${weixin.mp.token}")
    private String mpToken;
    @Value("${weixin.mp.message}")
    private String mpMessage;

    @Value("classpath:data/weixinMenu.json")
    private Resource menuRes;

    @Value("${weixin.mp.env}")
    private String env;

    @Autowired
    private ApiUserService userService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private MlsUserSer mlsUserSer;

    @Autowired
    private ApiAdService adService;

    @Autowired
    private ApiGoodsService goodsService;

    @Autowired
    private ApiOrderService orderService;
    @Autowired
    private ApiOrderGoodsService orderGoodsService;

    @Autowired
    private ApiAddressService addressService;

    @Autowired
    private ApiFeedbackService feedbackService;

    @Autowired
    private SendSms sendSms;

    @Autowired
    private ApiCartService cartService;

    @Autowired
    private ApiCouponService apiCouponService;

    @Autowired
    private ApiCollectService collectService;

    @Autowired
    private UserRecordSer userRecordSer;

    @Autowired
    private UserRecordActivitySer userRecordActivitySer;

    @Autowired
    private ApiOrderGoodsMapper apiOrderGoodsMapper;

    @Autowired
    private ApiUserCouponService userCouponService;

    @Autowired
    private ApiGoodsSpecificationService goodsSpecificationService;

    @Autowired
    private ApiGoodsGalleryService goodsGalleryService;
    @Autowired
    private ApiGoodsIssueService goodsIssueService;
    @Autowired
    private ApiBrandService brandService;
    @Autowired
    private ApiCommentService commentService;
    @Autowired
    private ApiCommentPictureService commentPictureService;

    @Autowired
    private ApiContractTplMapper apiContractTplMapper;

    @Autowired
    private ApiContractMapper apiContractMapper;

//    @Autowired
//    private ApiFxV3Controller apiFxV3Controller;

//    @Autowired
//    private ApiFxController apiFxController;

    @Autowired
    private ApiFxV4Controller apiFxV4Controller;

    @Autowired
    private WxOpenidMappingMapper wxOpenidMappingMapper;

    @IgnoreAuth
    @PostMapping("openidConvert")
    @ApiOperation("健国e商-openid转换")
    public void openidConvert() {

        String accessToken = tokenService.getAccessToken();
        logger.info("》》》weixin access token为：" + accessToken);

        // 请求地址
        String url = "https://api.weixin.qq.com/cgi-bin/changeopenid?access_token="+accessToken;
        // 要发送的数据对象

        List<UserVo> userVos = userService.queryList(null);
        List<List<UserVo>> partition = Lists.partition(userVos, 100);
        partition.forEach(list -> {
            JSONObject param = new JSONObject();
            param.put("from_appid", "wxc8dbd1f2ca69df9e");

            JSONArray openidList = new JSONArray();
            for(UserVo user : list){
                openidList.add(user.getWeixin_openid());
            }

            param.put("openid_list", openidList);

            System.out.println(param.toJSONString());
            // 发送post请求，并输出结果
            JSONObject result = restTemplate.postForObject(url, param, JSONObject.class);
            System.out.println("==>"+result.toJSONString());
            // {"errcode":0,"errmsg":"ok","result_list":[{"ori_openid":"owb4B6QbyOCyqHsDIRzjU9EdjxeY","new_openid":"oS8N75tquA0BjjBxn8aKP__FZhpw","err_msg":"ok"}]}
            // 解析新的openid
            JSONArray result_list = result.getJSONArray("result_list");

            if(result_list != null && result_list.size() > 0){
                for(int i = 0; i < result_list.size(); i++){
                    JSONObject jsonObject = result_list.getJSONObject(i);

                    WxOpenidMappingVo vo = new WxOpenidMappingVo();
                    vo.setNewOpenid(jsonObject.getString("new_openid"));
                    vo.setOriOpenid(jsonObject.getString("ori_openid"));

                    wxOpenidMappingMapper.insert(vo);
                }
            }

        });

    }

    @IgnoreAuth
    @GetMapping("tokenAuth")
    @ApiOperation("健国e商-token认证")
    public void tokenAuth(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter print;
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");

        logger.info("token认证，参数： signature={},timestamp={},nonce={},echostr={}", signature, timestamp, nonce, echostr);

        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        String[] arr = new String[]{mpToken, timestamp, nonce};
        if(arr != null && arr.length > 0){
            try {
                Arrays.sort(arr);
                String str = StringUtils.join(arr);
                String sec = DigestUtils.sha1Hex(str);

                if (signature != null && signature.equals(sec)) {
                    print = response.getWriter();
                    print.write(echostr);
                    print.flush();
                }
            } catch (Exception e) {
                logger.error("返回微信随机字符串echostr失败", e);
            }
        }
    }

    @IgnoreAuth
    @GetMapping("createMenu")
    @ApiOperation("健国e商-初始化菜单")
    public void createMenu() {

        String accessToken = tokenService.getAccessToken();
        logger.info("》》》weixin access token为：" + accessToken);

        String createMenuUrl = ApiUserUtils.getCreateMenuUrl(accessToken);
        logger.info("》》》自定义菜单url为：" + createMenuUrl);

        try {
            String weixinMenu = IOUtils.toString(menuRes.getInputStream(), Charset.forName("UTF-8"));

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
            HttpEntity<String> strEntity = new HttpEntity<String>(weixinMenu, headers);

            String res = restTemplate.postForObject(createMenuUrl, strEntity, String.class);

            logger.info("初始化菜单成功:"+res);
        } catch (Exception e) {
            logger.error("初始化菜单成功失败", e);
        }
    }

    @IgnoreAuth
    @ApiOperation("健国e商-回调地址验证")
    @GetMapping("MP_verify_UmBVd7Jhfh1DrRYt.txt")
    public String verify(HttpServletRequest request) {
        return "UmBVd7Jhfh1DrRYt";

    }

    @IgnoreAuth
    @ApiOperation("健国e商-订阅回调")
    @PostMapping("tokenAuth")
    public String postService(HttpServletRequest request) {
        Map<String, String> map = MessageUtil.xmlToMap(request);
        logger.debug("post服务，参数：{}", JSON.toJSONString(map));

        String toUserName = map.get("ToUserName");
        String fromUserName = map.get("FromUserName");
        String msgType = map.get("MsgType");
        String content = map.get("Content");
        String message = null;
        if (MessageType.MESSAGE_TEXT.equals(msgType)) {
            // 回复文本信息触发的消息
            message = MessageUtil.initText(toUserName, fromUserName, MessageType.MESSAGE_TEXT, content);
        } else if (MessageType.MESSAGE_EVENT.equals(msgType)) {
            // 关注时触发的消息
            String event = map.get("Event");
            if ("subscribe".equals(event)) {
                logger.info(fromUserName + "关注返回scene_str:{}", map.get("EventKey"));
                message = MessageUtil.initText(toUserName, fromUserName, MessageType.MESSAGE_TEXT, mpMessage);
            } else if ("unsubscribe".equals(event)) {
                logger.info(fromUserName + "取消关注");
            } else if ("VIEW".equals(event)) {
                // 点击链接
                logger.info(fromUserName + "点击链接");
            } else if ("SCAN".equals(event)) {
                // 扫码
                logger.info("扫码返回scene_str:" + map.get("EventKey"));
            }
        }
        return message;

    }

    /**
     * 登录公众号
     * 拦截器token控制是否已登录，没有登录则调用该方法
     *
     * 1. 普通关注用户，通过首页进入
     * a. 首页进入时，通过网页授权获取用户基本信息
     *
     *
     * 2. 通过推荐人分享链接进入==》分享url,带上推荐人id
     *
     *
     * 3. 通过推荐人二维码扫码进入==》分享url,带上推荐人id
     */
    @IgnoreAuth
    @ApiOperation(value = "登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "promoterId", value = "推荐人Id", dataType = "Integer", paramType = "query", required = false)
    })
    @GetMapping("loginMp")
    public Object loginMp(@RequestParam(value="promoterId", required = false) Integer promoterId){
        String scheme = request.getScheme();
        String serverName = request.getServerName();
        String path = request.getContextPath();
        String REDIRECT_URI = URLEncoder.encode(scheme + "://" + serverName + path +"/authorize.html");

        // 获取code
        String codeUrl = ApiUserUtils.getCode(REDIRECT_URI, "snsapi_userinfo", promoterId);
        log.info("loginMp方法，codeUlr={}", codeUrl);
        //由前端重定向
        return toResponsSuccess(codeUrl);
    }

    @IgnoreAuth
    @ApiOperation(value = "登录回调")
    @GetMapping("loginMpCallBack")
    public Object loginMpCallBack(HttpServletRequest request){
        UserVo userVo = null;
        Long promoterId = 0L;

            String code = request.getParameter("code");
            logger.info("》》》code:{}", code);

            String state = request.getParameter("state");
            logger.info("》》》state:{}", state);
            if(StringUtils.isNotEmpty(state) && !"null".equals(state)){
                try{
                    promoterId = Long.parseLong(state);
                }catch (Exception e){
                    logger.error("state转换成promoterId失败，state:"+state, e);
                }
            }

            // 通过code换取网页授权access_token
            String accessTokenUrl = ApiUserUtils.getWebAccess(code);
            String res = restTemplate.getForObject(accessTokenUrl, String.class);
            logger.info("accessTokenUrl res：{}", res);
            JSONObject sessionData = JSON.parseObject(res);

            String access_token = sessionData.getString("access_token");

            String openid = sessionData.getString("openid");
            if(StringUtils.isBlank(access_token) || StringUtils.isBlank(openid)){
                return toResponsFail("无效code");
            }

            userVo = userService.queryByOpenId(openid);
            if(userVo == null){
                String userUrl = ApiUserUtils.getUserMessage(access_token, openid);
                JSONObject userData = getUserJsonObject(userUrl);

                userVo = new UserVo();
                userVo.setWeixin_openid(openid);
                userVo.setNickname(userData.getString("nickname"));
                userVo.setUsername(Base64.encode(userVo.getNickname()));
                userVo.setPassword(openid);
                userVo.setRegister_time(new Date());
                userVo.setRegister_ip(RequestUtil.getIpAddrByRequest(request));
                userVo.setLast_login_ip(userVo.getRegister_ip());
                userVo.setLast_login_time(userVo.getRegister_time());
                userVo.setWeixin_openid(openid);
                userVo.setAvatar(userData.getString("headimgurl"));
                userVo.setGender(userData.getInteger("sex")); // //性别 0：未知、1：男、2：女
                userVo.setUser_level_id(1);// 默认为访客
                userVo.setProvince(userData.getString("province"));
                userVo.setCity(userData.getString("city"));
                userVo.setCountry(userData.getString("country"));
                userVo.setIsReal("1");// 未实名认证
                JSONArray privilege = userData.getJSONArray("privilege");
                if(privilege != null && privilege.size() > 0){
                    userVo.setPrivilege(privilege.toJSONString());
                }
                userVo.setUnionid(userData.getString("unionid"));


                //判断是否是推广用户登录
                Long fid = null;
                if(promoterId != 0){

                    Pair<UserVo, MlsUserEntity2> promoterUser = this.getUserObject(promoterId);

                    if(promoterUser != null){
                        userVo.setPromoterId(promoterId);
                        userVo.setPromoterName(promoterUser.getKey().getNickname());
                        userVo.setPromoterAvatar(promoterUser.getKey().getAvatar());

                        // 确定上级
                        //推荐人对应的分销用户
                        if(promoterUser.getKey().getUser_level_id() != null && promoterUser.getKey().getUser_level_id() > 2){
                            // 有代理身份的人b，推荐了一个a, a的推荐人是b，a的上级也是b
                            fid = promoterUser.getValue().getMlsUserId();
                        }else{
                            // 没有代理身份的人b, 推荐了游客a, a的推荐人b，a的上级是b的上级，也可能是没有上级
                            fid = promoterUser.getValue().getFid();
                        }
                    }
                }

                userService.save(userVo);

                // 初始化分销用户
                MlsUserEntity2 fmlsUser= new MlsUserEntity2();
                // 设置上级
                if(fid != null){
                    fmlsUser.setFid(fid);
                }else{
                    log.warn("login==>"+userVo.getNickname()+"授权登录进来，推荐人id:"+promoterId+"，目前没有上级，请注意");
                }

                fmlsUser.setUserId(userVo.getUserId());
                fmlsUser.setNickname(userVo.getNickname());
                fmlsUser.setUserName(Base64.encode(userVo.getNickname()));
                fmlsUser.setLoginPassword(userVo.getPassword());
                fmlsUser.setMerchantId(ApiConstant.DEFAULT_MERCHANT_ID);
                fmlsUser.setDeviceId(openid);
                this.mlsUserSer.insUser(fmlsUser);
            }else{// 如果之前已经存在，并且推荐人为空，那么需要修改下推荐人
                if(StringUtils.isEmpty(userVo.getPromoterName()) && promoterId != 0){

                    Pair<UserVo, MlsUserEntity2> promoterUser = this.getUserObject(promoterId);

                    if(promoterUser != null) {
                        userVo.setPromoterId(promoterId);
                        userVo.setPromoterName(promoterUser.getKey().getNickname());
                        userVo.setPromoterAvatar(promoterUser.getKey().getAvatar());
                    }

                    userService.update(userVo);

                    // 确定上级
                    //推荐人对应的分销用户
                    Long fid = null;
                    if(promoterUser.getKey().getUser_level_id() != null && promoterUser.getKey().getUser_level_id() > 2){
                        // 有代理身份的人b，推荐了一个a, a的推荐人是b，a的上级也是b
                        fid = promoterUser.getValue().getMlsUserId();
                    }else{
                        // 没有代理身份的人b, 推荐了游客a, a的推荐人b，a的上级是b的上级，也可能是没有上级
                        fid = promoterUser.getValue().getFid();
                    }

                    // 对应的分销用户信息
                    MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(userVo.getUserId());
                    if(fxUser.getFid() == null){
                        MlsUserEntity2  mlsUserVo = new MlsUserEntity2();
                        mlsUserVo.setMlsUserId(fxUser.getMlsUserId());
                        mlsUserVo.setFid(fid);
                        mlsUserSer.getEntityMapper().updateFid(mlsUserVo);
                    }
                }

            }

        Map<String, Object> resultObj = new HashMap<String, Object>();
        resultObj.put("userVo",userVo);

        return toResponsSuccess(resultObj);
    }

    private JSONObject getUserJsonObject(String userUrl) {
        String res;
        // 获取用户信息
//        String userUrl = ApiUserUtils.getUserMessage(access_token, openid);
        res = restTemplate.getForObject(userUrl, String.class);
        try {
            res = new String(res.getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.error("用户信息转换异常", e);
        }
        logger.info("userUrl res：{}", res);
        JSONObject userData = JSON.parseObject(res);
        logger.info(JSONObject.toJSONString(userData));
        return userData;
    }

    @ApiOperation(value = "更新微信用户信息（头像）")
    @IgnoreAuth
    @GetMapping(value = "updateWxUser")
    public Object updateWxUser(@RequestParam("openId") String openId) {
        List<UserVo> userVoList = new ArrayList<>();
        if("all".equals(openId)){
            userVoList = userService.queryList(null);
        }else{
            UserVo userVo = userService.queryByOpenId(openId);
            if(userVo == null){
                return toResponsFail("用户不存在");
            }
            userVoList.add(userVo);
        }

        if(CollectionUtils.isNotEmpty(userVoList)){
            userVoList.forEach(userVo -> {
                String accessToken = tokenService.getAccessToken();
                String userMessage = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN";
                String userUrl = String.format(userMessage, accessToken, userVo.getWeixin_openid());
                JSONObject userData = getUserJsonObject(userUrl);

                int subscribe = userData.getInteger("subscribe");
                UserVo user = new UserVo();
                user.setUserId(userVo.getUserId());
                user.setIs_return_cash(subscribe);
                if(userData.getInteger("subscribe") != 0){
                    user.setAvatar(userData.getString("headimgurl"));
                }
                userService.update(user);
            });
        }

        return toResponsSuccess(openId + "更新头像成功");
    }

    @ApiOperation(value = "首页banner图")
    @IgnoreAuth
    @GetMapping(value = "banner")
    public Object banner() {
        Map<String, Object> resultObj = new HashMap<>();

        Map<String, Object> param = new HashMap<>();
        param.put("ad_position_id", 1);
        List<AdVo> banner = adService.queryList(param);
        resultObj.put("banner", banner);

        return toResponsSuccess(resultObj);
    }


    @ApiOperation(value = "分销商品首页")
    @GetMapping(value = "index")
    public Object index(@LoginUser UserVo loginUser, @RequestParam(value = "page", defaultValue = "1") Integer page,
                        @RequestParam(value = "size", defaultValue = "10") Integer size,
                        @RequestParam("is_secKill") Integer is_secKill,
                        @RequestParam(value="promoterId", required = false) Long promoterId) {

        if(promoterId != null && promoterId > 0
                && !promoterId.equals(loginUser.getUserId())){
            // 更新推荐人
            if(loginUser.getPromoterId() == null || loginUser.getPromoterId() == 0){
                Pair<UserVo, MlsUserEntity2> promoterUser = this.getUserObject(promoterId);
                if(promoterUser != null){
                    loginUser.setPromoterId(promoterId);
                    loginUser.setPromoterName(promoterUser.getKey().getNickname());

                    userService.update(loginUser);

                    // 更新上级
                    // 确定上级
                    //推荐人对应的分销用户
                    Long fid = null;
                    if(promoterUser.getKey().getUser_level_id() != null && promoterUser.getKey().getUser_level_id() > 2){
                        // 有代理身份的人b，推荐了一个a, a的推荐人是b，a的上级也是b
                        fid = promoterUser.getValue().getMlsUserId();
                    }else{
                        // 没有代理身份的人b, 推荐了游客a, a的推荐人b，a的上级是b的上级，也可能是没有上级
                        fid = promoterUser.getValue().getFid();
                    }

                    // 对应的分销用户信息
                    MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
                    if(fxUser.getFid() == null){
                        MlsUserEntity2  mlsUserVo = new MlsUserEntity2();
                        mlsUserVo.setMlsUserId(fxUser.getMlsUserId());
                        mlsUserVo.setFid(fid);
                        mlsUserSer.getEntityMapper().updateFid(mlsUserVo);
                    }
                }
            }
        }

        //查询列表数据
        Map params = new HashMap();
        params.put("page", page);
        params.put("limit", size);
        params.put("sidx", "sort_order");
        params.put("order", "asc");
        params.put("is_delete", 0);
        params.put("is_on_sale", 1);
        params.put("is_secKill", is_secKill);
        Query query = new Query(params);
        List<GoodsVo> goodsList = goodsService.queryFxList(query);

        int total = goodsService.queryFxTotal(query);

        ApiPageUtils pageUtil = new ApiPageUtils(goodsList, total, query.getLimit(), query.getPage());

        return toResponsSuccess(pageUtil);
    }

    @ApiOperation(value = "获取微信请求参数")
    @PostMapping("wxconfig")
    public Object wxconfig(@LoginUser UserVo loginUser, @RequestParam("shareUrl") String shareUrl) {
        try {
            //有效期7200秒，开发者必须在自己的服务全局缓存jsapi_ticket
            Map jsapiTicket = JsonUtil.getObjet(RedisUtils.get("jsapiTicketKey"), Map.class);
            if (jsapiTicket == null || jsapiTicket.isEmpty() || jsapiTicket.get("ticket") == null) {
                String accessToken = tokenService.getAccessToken();

                String ticketUrl = ApiUserUtils.getTicketUrl(accessToken);
//                logger.info("》》》ticketUrl为：" + ticketUrl);

                String res = restTemplate.getForObject(ticketUrl, String.class);
//                logger.info("ticketUrl res：{}", res);
                JSONObject sessionData = JSON.parseObject(res);

                String ticket = sessionData.getString("ticket");

                Map<String, String> wxConfig = Sign.sign(ticket, shareUrl);
                wxConfig.put("appId", ApiUserUtils.getAppId());

                RedisUtils.set("jsapiTicketKey", JsonUtil.getJsonByObj(wxConfig), 7000);

                return toResponsSuccess(wxConfig);
            }

            return toResponsSuccess(jsapiTicket);
        } catch (Exception e) {
            logger.error("获取wx.config配置信息失败", e);
            return toResponsFail("获取wx.config配置信息失败");
        }
    }

    @ApiOperation(value = "获取支付的请求参数")
    @GetMapping("prepay")
    public Object prepay(@LoginUser UserVo loginUser, @RequestParam("orderId") Integer orderId) {
        String allOrderId = orderService.queryObject(orderId).getAll_order_id();
        List<OrderVo> orders = orderService.queryByAllOrderId(allOrderId);
        String body = null;
        BigDecimal allPrice = BigDecimal.ZERO;
        for(OrderVo o : orders) {
            if (null == o) {
                return toResponsObject(400, "订单已取消", "");
            }
            if (o.getPay_status().compareTo(1)> 0) {
                return toResponsObject(400, "订单已支付，请不要重复操作", "");
            }

            //计算总价格
            allPrice = allPrice.add(o.getActual_price());

            if(!(body == null)) {
                continue;
            }
            Map orderGoodsParam = new HashMap();
            orderGoodsParam.put("order_id", o.getId());
            //订单的商品
            List<OrderGoodsVo> orderGoods = orderGoodsService.queryList(orderGoodsParam);
            if (null != orderGoods) {
                for (OrderGoodsVo goodsVo : orderGoods) {
                    if(body == null) {
                        body = goodsVo.getGoods_name();
                    }else {
                        body = body+"等";
                        break;
                    }
                }
            }
        }

        String nonceStr = CharUtil.getRandomString(32);

        //https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3
        Map<Object, Object> resultObj = new TreeMap();

        try {
            Map<Object, Object> parame = new TreeMap<Object, Object>();
            parame.put("appid", ApiUserUtils.getAppId());
            // 商家账号。
            parame.put("mch_id", ApiUserUtils.getMchId());
            String randomStr = CharUtil.getRandomNum(18).toUpperCase();
            // 随机字符串
            parame.put("nonce_str", randomStr);
            // 商户订单编号
            parame.put("out_trade_no", allOrderId);
            // 商品描述
            parame.put("body", body);
            //支付金额
            if("local".equals(env) || allPrice.compareTo(BigDecimal.ZERO) == 0){
                allPrice = new BigDecimal("0.01");
            }
            parame.put("total_fee", allPrice.multiply(new BigDecimal(100)).intValue());
            System.out.println("***************"+parame.get("total_fee")+"***************");
            //System.out.println(orderInfo.getActual_price().multiply(new BigDecimal(100)).intValue() + "***************");
            //parame.put("total_fee", 1);
            // 回调地址
            parame.put("notify_url", ApiUserUtils.getNotifyUrl());
            // 交易类型APP
            parame.put("trade_type", ApiUserUtils.getTradeType());
            parame.put("spbill_create_ip", getClientIp());
            parame.put("openid", loginUser.getWeixin_openid());
            String sign = WechatUtil.arraySign(parame, ApiUserUtils.getPaySignKey());
            // 数字签证
            parame.put("sign", sign);

            String xml = MapUtils.convertMap2Xml(parame);
            System.out.println("***************xml="+xml+"***************");
            Map<String, Object> resultUn = XmlUtil.xmlStrToMap(WechatUtil.requestOnce(ApiUserUtils.getUniformorder(), xml));
            System.out.println("================resultUn="+resultUn+"================");

            // 响应报文
            String return_code = MapUtils.getString("return_code", resultUn);
            String return_msg = MapUtils.getString("return_msg", resultUn);
            //
            if (return_code.equalsIgnoreCase("FAIL")) {
                return toResponsFail("支付失败," + return_msg);
            } else if (return_code.equalsIgnoreCase("SUCCESS")) {
                // 返回数据
                String result_code = MapUtils.getString("result_code", resultUn);
                String err_code_des = MapUtils.getString("err_code_des", resultUn);
                if (result_code.equalsIgnoreCase("FAIL")) {
                    return toResponsFail("支付失败," + err_code_des);
                } else if (result_code.equalsIgnoreCase("SUCCESS")) {
                    String prepay_id = MapUtils.getString("prepay_id", resultUn);
                    // 先生成paySign 参考https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5
                    resultObj.put("appId", ApiUserUtils.getAppId());
                    //resultObj.put("timeStamp", DateUtils.timeToStr(System.currentTimeMillis() / 1000, DateUtils.DATE_TIME_PATTERN));
                    resultObj.put("timeStamp", System.currentTimeMillis() / 1000 + "");
                    resultObj.put("nonceStr", nonceStr);
                    resultObj.put("package", "prepay_id=" + prepay_id);
                    resultObj.put("signType", "MD5");
                    String paySign = WechatUtil.arraySign(resultObj, ApiUserUtils.getPaySignKey());
                    resultObj.put("paySign", paySign);

                    OrderVo newOrder = new OrderVo();
                    newOrder.setPay_id(prepay_id);
                    newOrder.setPay_status(1);
                    newOrder.setAll_order_id(allOrderId.toString());
                    orderService.updateStatus(newOrder);

                    //redis设置订单状态
                    RedisUtils.set(allOrderId.toString(), "51", 60*60*24);
                    return toResponsObject(0, "微信统一订单下单成功", resultObj);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return toResponsFail("下单失败,error=" + e.getMessage());
        }
        return toResponsFail("下单失败");
    }

    @ApiOperation(value = "余额支付")
    @GetMapping("amountpay")
    public Object amountpay(@LoginUser UserVo loginUser, @RequestParam("orderId") Integer orderId) {
        try{
            // 计算订单价格
            String allOrderId = orderService.queryObject(orderId).getAll_order_id();
            List<OrderVo> orders = orderService.queryByAllOrderId(allOrderId);
            BigDecimal allPrice = BigDecimal.ZERO;

            for(OrderVo o : orders) {
                if (null == o) {
                    return toResponsObject(400, "订单已取消", "");
                }
                if (o.getPay_status().compareTo(1)> 0) {
                    return toResponsObject(400, "订单已支付，请不要重复操作", "");
                }

                //计算总价格
                allPrice = allPrice.add(o.getActual_price());
            }

            // 扣减余额
            MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
            if (fxUser == null) {
                return toResponsFail("不存在该分销会员,userId" + loginUser.getUserId());
            }

            if(fxUser.getAllProfit() < allPrice.intValue()){
                return toResponsFail("余额不足，当前余额为："+fxUser.getAllProfit());
            }

            UserRecord ur = new UserRecord();
            ur.setMlsUserId(fxUser.getMlsUserId());
            ur.setTypes(3);
            ur.setTypesStr("余额支付");
            ur.setPrice(allPrice.intValue());
            ur.setRemarks(fxUser.getMlsUserId()+"用余额支付："+allPrice.intValue());
            ur.setOrderId(orderId);
            ur.setAmount(new BigDecimal(fxUser.getAllProfit() - allPrice.intValue()));
            ur.setDirection(-1);
            userRecordSer.save(ur);

            MlsUserEntity2 mlsUserVo= new MlsUserEntity2();
            mlsUserVo.setMlsUserId(fxUser.getMlsUserId());
            mlsUserVo.setTodaySales(allPrice.intValue());
            mlsUserVo.setGetProfit(-allPrice.intValue());
            mlsUserSer.updateMoney(mlsUserVo);

            // 更改订单状态
            OrderVo orderInfo = new OrderVo();
            orderInfo.setAll_order_id(allOrderId);
            orderInfo.setPay_status(2);
            orderInfo.setOrder_status(2);
            orderInfo.setShipping_status(0);
            orderInfo.setPay_time(new Date());
            orderService.updateStatus(orderInfo);

            // allOrderId表示总订单id, 可能有多个供货商，所以orders是一个list,但目前健国e商只有一个
            OrderVo vo = null;
            for(OrderVo v : orders) {
                vo = v;

                sendNoticeBySms(v);

                try {
                    //调用分销接口
//                    fx(vo.getUser_id(), vo.getOrder_price(), vo.getId());

//                    apiFxController.fxV2(vo.getUser_id(), vo.getOrder_price(), vo.getId());

//                    apiFxV3Controller.fxV3(vo.getUser_id(), vo.getOrder_price(), vo.getId());
                    apiFxV4Controller.fxV4(vo.getUser_id(), vo.getOrder_price(), vo.getId());
                }catch(Exception e) {
                    System.out.println("================分销错误开始================");
                    log.error("分销失败", e);
                    System.out.println("================分销错误结束================");
                }
            }
            return toResponsSuccess("余额支付成功");
        }catch (Exception e){
            e.printStackTrace();
        }
        return toResponsFail("余额支付失败");
    }

    @ApiOperation(value = "积分支付")
    @GetMapping("pointspay")
    public Object pointspay(@LoginUser UserVo loginUser, @RequestParam("orderId") Integer orderId) {
        try{
            // 计算订单价格
            String allOrderId = orderService.queryObject(orderId).getAll_order_id();
            List<OrderVo> orders = orderService.queryByAllOrderId(allOrderId);
            BigDecimal allPrice = BigDecimal.ZERO;

            for(OrderVo o : orders) {
                if (null == o) {
                    return toResponsObject(400, "订单已取消", "");
                }
                if (o.getPay_status().compareTo(1)> 0) {
                    return toResponsObject(400, "订单已支付，请不要重复操作", "");
                }

                // 获取订单对应的商品
                Map<String, Object> queryMap = new HashMap<>();
                queryMap.put("order_id", o.getId());
                List<OrderGoodsVo> orderGoodsVoList = orderGoodsService.queryList(queryMap);
                for(OrderGoodsVo og : orderGoodsVoList){
                    GoodsVo goodsVo = goodsService.queryObject(og.getGoods_id());

                    if(!goodsVo.getIs_secKill().equals(1)){
                        return toResponsObject(400, "积分不能用于购买套餐，请用微信或余额支付", "");
                    }

                    //计算总价格，积分只能零售价购买
                    allPrice = allPrice.add(goodsVo.getRetail_price().multiply(new BigDecimal(og.getNumber())));
                }
            }

            // 扣减余额
            MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
            if (fxUser == null) {
                return toResponsFail("不存在该分销会员,userId" + loginUser.getUserId());
            }

            if(fxUser.getPoints() < allPrice.intValue()){
                return toResponsFail("积分不足，当前积分为："+fxUser.getPoints());
            }

            UserRecord ur = new UserRecord();
            ur.setMlsUserId(fxUser.getMlsUserId());
            ur.setTypes(6);
            ur.setTypesStr("积分支付");
            ur.setPrice(allPrice.intValue());
            ur.setRemarks(fxUser.getMlsUserId()+"用积分支付："+allPrice.intValue()+"，剩余积分："+(fxUser.getPoints() - allPrice.intValue()));
            ur.setOrderId(orderId);
            ur.setAmount(new BigDecimal(fxUser.getAllProfit()));
            ur.setDirection(-1);
            userRecordSer.save(ur);

            MlsUserEntity2 mlsUserVo= new MlsUserEntity2();
            mlsUserVo.setMlsUserId(fxUser.getMlsUserId());
            mlsUserVo.setTodaySales(allPrice.intValue());
            mlsUserVo.setGetPoints(-allPrice.intValue());
            mlsUserSer.updateMoney(mlsUserVo);

            // 更改订单状态
            OrderVo orderInfo = new OrderVo();
            orderInfo.setAll_order_id(allOrderId);
            orderInfo.setPay_status(2);
            orderInfo.setOrder_status(2);
            orderInfo.setShipping_status(0);
            orderInfo.setPay_time(new Date());
            orderService.updateStatus(orderInfo);

            // allOrderId表示总订单id, 可能有多个供货商，所以orders是一个list,但目前健国e商只有一个
            for(OrderVo v : orders) {
                sendNoticeBySms(v);
                //不用分销
            }
            return toResponsSuccess("积分支付成功");
        }catch (Exception e){
            e.printStackTrace();
        }
        return toResponsFail("积分支付失败");
    }

    private void sendNoticeBySms(OrderVo v) {
        try{
            StringBuffer buyGoodsDesc = new StringBuffer();
            Map<String, Object> params = new HashMap<>();
            params.put("order_id", v.getId());
            // 获取订单关联的商品
            List<OrderGoodsVo> orderGoodsVoList = apiOrderGoodsMapper.queryList(params);
            orderGoodsVoList.forEach(orderGoodsVo -> {
                buyGoodsDesc.append(orderGoodsVo.getGoods_name()+"："+orderGoodsVo.getNumber()+"（盒）").append("\r\n");
            });

            List<String> templateParams = new ArrayList<>();
            templateParams.add(DateUtils.format(v.getAdd_time(), DateUtils.DATE_TIME_PATTERN));
            templateParams.add(buyGoodsDesc.toString());
            templateParams.add(v.getConsignee());
            templateParams.add(v.getMobile());
            templateParams.add(v.getProvince() + v.getCity() + v.getDistrict() + "-" + v.getAddress());

            List<String> mobileList = null;
            String mobiles = mlsUserSer.getEntityMapper().queryByKey("send_notice_mobiles");
            if(StringUtils.isNotBlank(mobiles)){
                String[] mobileArr = mobiles.split(",");
                mobileList = Arrays.asList(mobileArr);
            }
            sendSms.send(templateParams, SendSms.SEND_NOTICE_TEMPLATEID, mobileList);
        }catch (Exception e){
            log.error("发货通知失败", e);
        }
    }

    /**
     * 微信订单回调接口
     *
     * @return
     */
    @ApiOperation(value = "微信订单回调接口")
    @PostMapping(value = "notify", produces = "text/html;charset=UTF-8")
    @IgnoreAuth
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        try {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*");
            InputStream in = request.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            out.close();
            in.close();
            //xml数据
            String reponseXml = new String(out.toByteArray(), "utf-8");

            WechatRefundApiResult result = (WechatRefundApiResult) XmlUtil.xmlStrToBean(reponseXml, WechatRefundApiResult.class);

            //处理订单的redis状态
            String value = RedisUtils.get(result.getOut_trade_no().toString());
            if(value != null && "51".equals(value)) {
                RedisUtils.del(result.getOut_trade_no().toString());
            }else {
                //查询支付已结操作过
                response.getWriter().write(ApiUserUtils.setXml("SUCCESS", "OK"));
                return;
            }

            String result_code = result.getResult_code();
            if (result_code.equalsIgnoreCase("FAIL")) {
                //订单编号
                String out_trade_no = result.getOut_trade_no();
                logger.error("订单" + out_trade_no + "支付失败");
                response.getWriter().write(ApiUserUtils.setXml("SUCCESS", "OK"));
            } else if (result_code.equalsIgnoreCase("SUCCESS")) {
                Map<Object, Object> retMap = XmlUtil.xmlStrToTreeMap(reponseXml);
                String sign = WechatUtil.arraySign(retMap, ApiUserUtils.getPaySignKey());
                if(!sign.equals(result.getSign())) {//判断签名
                    return;
                }

                // 更改订单状态
                // 业务处理
                OrderVo orderInfo = new OrderVo();
                orderInfo.setAll_order_id(result.getOut_trade_no());
                orderInfo.setPay_status(2);
                orderInfo.setOrder_status(2);// 已支付，待发货
                orderInfo.setShipping_status(0);
                orderInfo.setPay_time(new Date());
                orderService.updateStatus(orderInfo);

                Map<String, Object> map = new HashMap<String, Object>();
                map.put("all_order_id", result.getOut_trade_no());
                List<OrderVo> lists = orderService.queryList(map);
                OrderVo vo = null;
                for(OrderVo v : lists) {
                    vo = v;

                    sendNoticeBySms(v);

                    try {
                        MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(vo.getUser_id());

                        UserRecord ur = new UserRecord();
                        ur.setMlsUserId(fxUser.getMlsUserId());
                        ur.setTypes(5);
                        ur.setTypesStr("微信支付");
                        ur.setPrice(vo.getOrder_price().intValue());
                        ur.setRemarks(fxUser.getMlsUserId() +"用微信支付："+vo.getOrder_price().intValue());
                        ur.setOrderId(vo.getId());
                        ur.setAmount(new BigDecimal(fxUser.getAllProfit()));
                        ur.setDirection(-1);
                        userRecordSer.save(ur);

                        //调用分销接口
//                        fx(vo.getUser_id(), vo.getOrder_price(), vo.getId());

//                        apiFxController.fxV2(vo.getUser_id(), vo.getOrder_price(), vo.getId());

//                        apiFxV3Controller.fxV3(vo.getUser_id(), vo.getOrder_price(), vo.getId());
                        apiFxV4Controller.fxV4(vo.getUser_id(), vo.getOrder_price(), vo.getId());
                    }catch(Exception e) {
                        System.out.println("================分销错误开始================");
                        log.error("分销失败", e);
                        System.out.println("================分销错误结束================");
                    }
                }

                response.getWriter().write(ApiUserUtils.setXml("SUCCESS", "OK"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }

    /**
     * 获取用户优惠券列表
     *  优惠券状态 couponStatus: 1 可用 2 已用 3 过期
     */
    @ApiOperation(value = "获取用户优惠券列表")
    @GetMapping("getUserCoupons")
    public Object getUserCoupons(@LoginUser UserVo loginUser, @RequestParam("couponStatus") Integer couponStatus) {
        Map param = new HashMap();
        param.put("user_id", loginUser.getUserId());
        param.put("coupon_status", couponStatus);
        List<CouponVo> couponVos = apiCouponService.queryUserCoupons(param);
        return toResponsSuccess(couponVos);
    }

    @ApiOperation(value = "获取购物车")
    @GetMapping("getCart")
    public Object getCart(@LoginUser UserVo loginUser) {
        Map<String, Object> resultObj = new HashMap();
        //查询列表数据
        Map param = new HashMap();
        param.put("user_id", loginUser.getUserId());
        List<CartVo> cartList = cartService.queryList(param);
        //获取购物车统计信息
        Integer goodsCount = 0;
        BigDecimal goodsAmount = new BigDecimal(0.00);
        Integer checkedGoodsCount = 0;
        BigDecimal checkedGoodsAmount = new BigDecimal(0.00);
        for (CartVo cartItem : cartList) {
            goodsCount += cartItem.getNumber();
            goodsAmount = goodsAmount.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            if (null != cartItem.getChecked() && 1 == cartItem.getChecked()) {
                checkedGoodsCount += cartItem.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            }
        }

        resultObj.put("cartList", cartList);
        //
        Map<String, Object> cartTotal = new HashMap();
        cartTotal.put("goodsCount", goodsCount);
        cartTotal.put("goodsAmount", goodsAmount);
        cartTotal.put("checkedGoodsCount", checkedGoodsCount);
        cartTotal.put("checkedGoodsAmount", checkedGoodsAmount);
        //
        resultObj.put("cartTotal", cartTotal);
        return resultObj;
    }

    @ApiOperation(value = "更新购物车商品选择状态")
    @GetMapping("updateCartChecked")
    public Object updateCartCheck(@LoginUser UserVo loginUser, @RequestParam(value = "goodsIds", required = false) String goodsIds) {
        //查询列表数据
        Map param = new HashMap();
        param.put("user_id", loginUser.getUserId());
        List<CartVo> cartList = cartService.queryList(param);

        if(StringUtils.isNotBlank(goodsIds)){
            String[] goodsIdsArr = goodsIds.split(",");
            if(goodsIdsArr != null && goodsIdsArr.length > 0){

                List goodsIdList = Arrays.asList(goodsIdsArr);

                for (CartVo cartItem : cartList) {
                    if(goodsIdList.contains(cartItem.getGoods_id().toString())){
                        cartItem.setChecked(1);
                    }else{
                        cartItem.setChecked(0);
                    }
                    cartService.update(cartItem);
                }
            }
        }else{
            for (CartVo cartItem : cartList) {
                cartItem.setChecked(0);
                cartService.update(cartItem);
            }
        }

        return toResponsSuccess(getCart(loginUser));
    }

    /**
     * 添加商品到购物车
     */
    @ApiOperation(value = "添加商品到购物车")
    @GetMapping("addCart")
    public Object addCart(@LoginUser UserVo loginUser, @RequestParam("goodsId") Integer goodsId, @RequestParam("number") Integer number) {
        //判断商品是否可以购买
        GoodsVo goodsInfo = goodsService.queryObject(goodsId);
        if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() != 1) {
            return this.toResponsObject(400, "商品已下架", "");
        }

        if (goodsInfo.getIs_secKill().equals(5) && !hasActivityPerm(loginUser)) return this.toResponsObject(400, "您当前没有权限参与该活动，请联系上级代理商授权", "");

        //取得规格的信息,判断规格库存
        if (goodsInfo.getGoods_number() < number) {
            return this.toResponsObject(400, "库存不足", "");
        }

        //判断购物车中是否存在此规格商品
        Map cartParam = new HashMap();
        cartParam.put("goods_id", goodsId);
        cartParam.put("user_id", loginUser.getUserId());
        List<CartVo> cartInfoList = cartService.queryList(cartParam);
        CartVo cartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
        if (null == cartInfo) {
            //添加操作
            cartInfo = new CartVo();
            cartInfo.setGoods_id(goodsId);
            cartInfo.setProduct_id(goodsId);
            cartInfo.setGoods_sn(goodsInfo.getGoods_sn());
            cartInfo.setGoods_name(goodsInfo.getName());
            cartInfo.setList_pic_url(goodsInfo.getList_pic_url());
            cartInfo.setNumber(number);
            cartInfo.setSession_id("1");
            cartInfo.setUser_id(loginUser.getUserId());

            cartInfo.setRetail_price(ApiUserUtils.getActualPrice(loginUser, goodsInfo));

            cartInfo.setMarket_price(goodsInfo.getMarket_price());
            cartInfo.setChecked(1);
            cartInfo.setMerchant_id(goodsInfo.getMerchantId());
            cartService.save(cartInfo);
        } else {
            //如果已经存在购物车中，则数量增加
            if (goodsInfo.getGoods_number() < (number + cartInfo.getNumber())) {
                return this.toResponsObject(400, "库存不足", "");
            }
            cartInfo.setNumber(cartInfo.getNumber() + number);
            cartService.update(cartInfo);
        }
        return toResponsSuccess(getCart(loginUser));
    }

    /**
     * 减少商品到购物车
     */
    @ApiOperation(value = "减少商品到购物车")
    @GetMapping("minusCart")
    public Object minusCart(@LoginUser UserVo loginUser, @RequestParam("goodsId") Integer goodsId, @RequestParam("number") Integer number) {
        //判断购物车中是否存在此规格商品
        Map cartParam = new HashMap();
        cartParam.put("goods_id", goodsId);
        cartParam.put("user_id", loginUser.getUserId());
        List<CartVo> cartInfoList = cartService.queryList(cartParam);
        CartVo cartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
        int cart_num = 0;
        if (null != cartInfo) {
            if (cartInfo.getNumber() > number) {
                cartInfo.setNumber(cartInfo.getNumber() - number);
                cartService.update(cartInfo);
                cart_num = cartInfo.getNumber();
            } else {
                cartService.delete(cartInfo.getId());
                cart_num = 0;
            }
        }
        return toResponsSuccess(getCart(loginUser));
    }

    @ApiOperation(value = "立即购买")
    @GetMapping("buyGoods")
    public Object buyGoods(@LoginUser UserVo loginUser, @RequestParam("goodsId") Integer goodsId, @RequestParam("number") Integer number) {
        //判断商品是否可以购买
        GoodsVo goodsInfo = goodsService.queryObject(goodsId);

        if (goodsInfo.getIs_secKill().equals(5) && !hasActivityPerm(loginUser)) return this.toResponsObject(400, "您当前没有权限参与该活动，请联系上级代理商授权", "");

        if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() != 1) {
            return this.toResponsObject(400, "商品已下架", "");
        }
        //判断库存
        if (null == goodsInfo || goodsInfo.getGoods_number() < number) {
            return this.toResponsObject(400, "库存不足", "");
        }


        BuyGoodsVo goodsVo = new BuyGoodsVo();
        goodsVo.setGoodsId(goodsId);
        goodsVo.setProductId(goodsId);
        goodsVo.setNumber(number);

        J2CacheUtils.put(J2CacheUtils.SHOP_CACHE_NAME, "goods" + loginUser.getUserId() + "", goodsVo);
        return toResponsMsgSuccess("添加成功");
    }

    private boolean hasActivityPerm(UserVo loginUser) {
        // 活动商品需要判断是否有购买权限
        ActivitySign activitySign = apiActivitySignService.getActivityNotBuy(loginUser.getUserId());
        return activitySign != null;
    }

    /**
     * 获取用户收藏
     */
    @ApiOperation(value = "添加取消收藏")
    @GetMapping("addorDelCollect")
    public Object addorDelCollect(@LoginUser UserVo loginUser, @RequestParam("goodsId")  Integer goodsId) {
        Map param = new HashMap();
        param.put("user_id", loginUser.getUserId());
        param.put("type_id", goodsId);
        param.put("value_id", goodsId);
        List<CollectVo> collectEntities = collectService.queryList(param);
        //
        Integer collectRes = null;
        String handleType = "add";
        if (null == collectEntities || collectEntities.size() < 1) {
            CollectVo collectEntity = new CollectVo();
            collectEntity.setAdd_time(System.currentTimeMillis() / 1000);
            collectEntity.setType_id(goodsId);
            collectEntity.setValue_id(goodsId);
            collectEntity.setIs_attention(0);
            collectEntity.setUser_id(loginUser.getUserId());
            //添加收藏
            collectRes = collectService.save(collectEntity);
        } else {
            //取消收藏
            collectRes = collectService.delete(collectEntities.get(0).getId());
            handleType = "delete";
        }

        if (collectRes > 0) {
            Map data = new HashMap();
            data.put("type", handleType);
            return toResponsSuccess(data);
        }
        return toResponsFail("操作失败");
    }

    @ApiOperation(value = "结算列表")
    @GetMapping("checkoutList")
    public Object checkoutList(@LoginUser UserVo loginUser, @RequestParam(value = "type", required = false) String type) {
        Map resultObj = new HashMap();

        Map<String, Object> param = new HashMap<String, Object>();
        param.put("user_id", loginUser.getUserId());
        List<CartVo> cartList = new ArrayList<>();
        if ("cart".equals(type)) {//购物车提交
            //查询列表数据
            param.put("checked", 1);
            cartList = cartService.queryList(param);
        }else{
            BuyGoodsVo goodsVo = (BuyGoodsVo) J2CacheUtils.get(J2CacheUtils.SHOP_CACHE_NAME,
                    "goods" + loginUser.getUserId());
            if (null == goodsVo) {
                resultObj.put("errno", 400);
                resultObj.put("errmsg", "请选择商品");
                return toResponsSuccess(resultObj);
            }
            GoodsVo goods = goodsService.queryObject(goodsVo.getGoodsId());
            BigDecimal retailPrice = ApiUserUtils.getActualPrice(loginUser, goods);

            CartVo cartVo = new CartVo();
            cartVo.setChecked(1);
            cartVo.setNumber(goodsVo.getNumber());
            cartVo.setRetail_price(retailPrice);
            cartVo.setGoods_sn(goods.getGoods_sn());
            cartVo.setMarket_price(goods.getMarket_price());
            cartVo.setGoods_name(goods.getName());
            cartVo.setList_pic_url(goods.getList_pic_url());
            cartVo.setGoods_id(goodsVo.getGoodsId());
            cartVo.setSession_id("1");
            cartVo.setUser_id(loginUser.getUserId());

            cartList.add(cartVo);
        }
        resultObj.put("cartList", cartList);

        List<AddressVo> addressEntities = addressService.queryList(param);
        resultObj.put("addressList", addressEntities);

        param.put("coupon_status", "1");
        // 如果不是单品，则不能使用活动现金券
//        <i-option value="1">普通商品</i-option>
//        <i-option value="4">套餐商品</i-option>
//        <i-option value="5">活动商品</i-option>
        boolean eableUse = true;
        for (CartVo cartVo : cartList) {
            GoodsVo goodsVo = goodsService.queryObject(cartVo.getGoods_id());
            if(goodsVo.getIs_secKill().equals(4) || goodsVo.getIs_secKill().equals(5)){
                eableUse = false;
                break;
            }
        }
        if(!eableUse){
            param.put("coupon_id", 30);
        }
        List<CouponVo> couponList = apiCouponService.queryUserCoupons(param);
        resultObj.put("couponList", couponList);

        return toResponsSuccess(resultObj);
    }

    @ApiOperation(value = "订单提交")
    @GetMapping("submitOrder")
    public Object submitOrder(@LoginUser UserVo loginUser,
                              @RequestParam(value = "couponIds", required = false) String couponIds,
                              @RequestParam(value = "type", required = false) String type,
                              @RequestParam("addressId") Integer addressId,
                              @RequestParam(value="postscript", required = false) String postscript) {
        Map resultObj = null;
        try {
            resultObj = orderService.submitOrder(couponIds, type, addressId, postscript, loginUser);
            if (null != resultObj) {
                return toResponsObject(org.apache.commons.collections.MapUtils.getInteger(resultObj, "errno"), org.apache.commons.collections.MapUtils.getString(resultObj, "errmsg"), resultObj.get("data"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return toResponsFail("提交失败");
    }

    @ApiOperation(value = "获取订单列表")
    @GetMapping("listOrder")
    public Object listOrder(@LoginUser UserVo loginUser, @RequestParam(value = "order_status", required = false) Integer order_status,
                       @RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "size", defaultValue = "10") Integer size) {
        //
        Map params = new HashMap();
        params.put("user_id", loginUser.getUserId());
        params.put("page", page);
        params.put("limit", size);
        params.put("sidx", "id");
        params.put("order", "desc");
        params.put("order_status", order_status);
        //查询列表数据
        Query query = new Query(params);
        List<OrderVo> orderEntityList = orderService.queryList(query);
        int total = orderService.queryTotal(query);

        ApiPageUtils pageUtil = new ApiPageUtils(orderEntityList, total, query.getLimit(), query.getPage());
        //
        for (OrderVo item : orderEntityList) {
            Map orderGoodsParam = new HashMap();
            orderGoodsParam.put("order_id", item.getId());
            //订单的商品
            List<OrderGoodsVo> goodsList = orderGoodsService.queryList(orderGoodsParam);

            int goodsCount = 0;
            for(OrderGoodsVo orderGoodsVo : goodsList){
                goodsCount += orderGoodsVo.getNumber();
            }

            item.setGoodsCount(goodsCount);
            item.setOrderGoodsList(goodsList);

        }
        return toResponsSuccess(pageUtil);
    }


    @ApiOperation(value = "获取订单详情")
    @GetMapping("detailOrder")
    public Object detailOrder(@RequestParam("orderId") Integer orderId) {
        Map resultObj = new HashMap();
        //
        OrderVo orderInfo = orderService.queryObject(orderId);
        if (null == orderInfo) {
            return toResponsObject(400, "订单不存在", "");
        }
        Map orderGoodsParam = new HashMap();
        orderGoodsParam.put("order_id", orderId);
        //订单的商品
        List<OrderGoodsVo> orderGoods = orderGoodsService.queryList(orderGoodsParam);

        //订单可操作的选择,删除，支付，收货，评论，退换货
        Map handleOption = orderInfo.getHandleOption();
        //
        resultObj.put("orderInfo", orderInfo);
        resultObj.put("orderGoods", orderGoods);
        resultObj.put("handleOption", handleOption);
        if (!StringUtils.isEmpty(orderInfo.getShipping_code()) && !StringUtils.isEmpty(orderInfo.getShipping_no())) {
            resultObj.put("shippingList", null);
        }
        return toResponsSuccess(resultObj);
    }


    @ApiOperation(value = "确认收货")
    @GetMapping("confirmOrder")
    public Object confirmOrder(@RequestParam("orderId") Integer orderId) {
        try {
            OrderVo orderVo = orderService.queryObject(orderId);
            orderVo.setOrder_status(4);// 用户已确认收货
            orderVo.setShipping_status(2);
            orderVo.setConfirm_time(new Date());
            orderService.update(orderVo);
            return toResponsSuccess("确认收货成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return toResponsFail("提交失败");
    }

    @ApiOperation(value = "个人信息")
    @GetMapping("getUserInfo")
    public Object getUserInfo(@LoginUser UserVo loginUser) {

        MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
        if(fxUser.getLockProfit() == null){
            fxUser.setLockProfit(0);
        }
        // 计算可用余额
        if(fxUser.getAllProfit() != null && fxUser.getAllProfit() >=  fxUser.getLockProfit()){
            fxUser.setAllProfit(fxUser.getAllProfit() - fxUser.getLockProfit());
        }
        loginUser.setMlsuser(fxUser);

        if(loginUser.getPromoterId() != null && loginUser.getPromoterId() > 0){
            UserVo promoterUser = userService.queryObject(loginUser.getPromoterId());
            if(promoterUser != null){
                loginUser.setPromoterName(promoterUser.getNickname());
                loginUser.setPromoterAvatar(promoterUser.getAvatar());
            }
        }

        return toResponsSuccess(loginUser);
    }

    @ApiOperation(value = "获取用户信息")
    @GetMapping("getUserDetail")
    public Object getUserDetail(Long userId) {

        if(userId > ApiConstant.BASE_ID){
            userId -= ApiConstant.BASE_ID;
        }

        UserVo userVo = userService.queryObject(userId);

        if(StringUtils.isEmpty(userVo.getRealName())){
            userVo.setRealName(userVo.getNickname());
        }
        userVo.setLevelName(ApiUserUtils.getLevelName(userVo.getUser_level_id()));

        return toResponsSuccess(userVo);
    }

    /**
     * 发送短信
     */
    @ApiOperation(value = "发送短信")
    @GetMapping("smsCode")
    public Object smsCode(@RequestParam("mobile") String mobile) {
        if(RedisUtils.exists("sms" + mobile)){
            return toResponsSuccess("请勿重复发送短信");
        }

        sendCode(mobile);

        return toResponsSuccess("发送短信成功");
    }

    /**
     * 绑定手机
     */
    @ApiOperation(value = "绑定手机")
    @GetMapping("bindMobile")
    public Object bindMobile(@LoginUser UserVo loginUser, @RequestParam("verificationCode") String verificationCode, @RequestParam("mobile") String mobile) {
        if (!verificationCode(mobile, verificationCode)) {
            return toResponsFail("验证码错误");
        }
        UserVo userVo = userService.queryObject(loginUser.getUserId());
        userVo.setMobile(mobile);
        userService.update(userVo);
        return toResponsSuccess("手机绑定成功");
    }

    @ApiOperation(value = "修改用户个人信息")
    @GetMapping("updateUserInfo")
    public Object updateUserInfo(@LoginUser UserVo loginUser, @RequestParam("realName") String realName,
                             @RequestParam("idCard") String idCard,
                             @RequestParam("bankCard") String bankCard,
                                 @RequestParam("keywords") String keywords,
                                 @RequestParam("compName") String compName,
                                 @RequestParam("position") String position,
                                 @RequestParam("compAddr") String compAddr,
                                 @RequestParam("indAdvance") String indAdvance,
                                 @RequestParam("supplyRes") String supplyRes,
                                 @RequestParam("needRes") String needRes) {
        UserVo userVo = userService.queryObject(loginUser.getUserId());
        userVo.setRealName(realName);
        userVo.setIdCard(idCard);
        userVo.setBankCard(bankCard);
        userVo.setKeywords(keywords);
        userVo.setCompName(compName);
        userVo.setPosition(position);
        userVo.setCompAddr(compAddr);
        userVo.setIndAdvance(indAdvance);
        userVo.setSupplyRes(supplyRes);
        userVo.setNeedRes(needRes);
        userService.update(userVo);
        return toResponsSuccess("修改用户个人信息成功");
    }

    @ApiOperation(value = "个人认证")
    @GetMapping("personCert")
    public Object personCert(@LoginUser UserVo loginUser,
                       @RequestParam("idCard") String idCard,
                       @RequestParam("realName") String realName,
                       @RequestParam("bankCard") String bankCard,
                       @RequestParam("mobile") String mobile) {
        UserVo userVo = userService.queryObject(loginUser.getUserId());
        userVo.setIdCard(idCard);
        userVo.setRealName(realName);
        userVo.setBankCard(bankCard);
        userVo.setMobile(mobile);
        userVo.setCertType("1");
        userVo.setIsReal("2");
        userService.update(userVo);
        return toResponsSuccess("个人认证成功");
    }

    @ApiOperation(value = "企业认证")
    @GetMapping("companyCert")
    public Object companyCert(@LoginUser UserVo loginUser,
                       @RequestParam("idCard") String idCard,
                       @RequestParam("realName") String realName,
                       @RequestParam("companyName") String companyName,
                       @RequestParam("creditCode") String creditCode,
                       @RequestParam("busiLicenseUrl") String busiLicenseUrl,
                       @RequestParam("mobile") String mobile) {
        UserVo userVo = userService.queryObject(loginUser.getUserId());
        userVo.setIdCard(idCard);
        userVo.setRealName(realName);
        userVo.setCompanyName(companyName);
        userVo.setCreditCode(creditCode);
        userVo.setBusiLicenseUrl(busiLicenseUrl);
        userVo.setMobile(mobile);
        userVo.setCertType("2");
        userVo.setIsReal("2");
        userService.update(userVo);
        return toResponsSuccess("企业认证成功");
    }

    // 新增收货地址
    /**
     * 添加或更新收货地址
     */
    @ApiOperation(value = "添加或更新收货地址", response = Map.class)
    @PostMapping("saveOrUpdateAddr")
    public Object saveOrUpdateAddr(@LoginUser UserVo loginUser, @RequestBody AddressVo entity) {

        entity.setUserId(loginUser.getUserId());

        Map<String, Object> param = new HashMap<String, Object>();
        param.put("user_id", loginUser.getUserId());

        List<AddressVo> addressEntities = addressService.queryList(param);
        if(addressEntities == null || addressEntities.size()==0){//第一次添加设置为默认地址
            entity.setIs_default(1);
        }else{
            if(entity.getIs_default() == 1){// 新增一个默认地址，或者修改为默认地址
                for(AddressVo vo : addressEntities){
                    vo.setIs_default(0);
                    addressService.update(vo);
                }
            }
        }

        if (null == entity.getId() || entity.getId() == 0) {
            entity.setId(null);
            addressService.save(entity);
        } else {
            addressService.update(entity);
        }
        return toResponsSuccess(entity);
    }

    /**
     * 获取用户的收货地址
     */
    @ApiOperation(value = "获取用户的收货地址接口", response = Map.class)
    @GetMapping("listAddr")
    public Object listAddr(@LoginUser UserVo loginUser) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("user_id", loginUser.getUserId());
        List<AddressVo> addressEntities = addressService.queryList(param);
        return toResponsSuccess(addressEntities);
    }

    /**
     * 获取收货地址的详情
     */
    @ApiOperation(value = "获取收货地址的详情", response = Map.class)
    @GetMapping("detailAddr")
    public Object detailAddr(@RequestParam("id") Integer id, @LoginUser UserVo loginUser) {
        AddressVo entity = addressService.queryObject(id);
        //判断越权行为
        if (!entity.getUserId().equals(loginUser.getUserId())) {
            return toResponsObject(403, "您无权查看", "");
        }
        return toResponsSuccess(entity);
    }

    /**
     * 删除指定的收货地址
     */
    @ApiOperation(value = "删除指定的收货地址", response = Map.class)
    @GetMapping("delAddr")
    public Object delAddr(@RequestParam("id") Integer id, @LoginUser UserVo loginUser) {
        AddressVo entity = addressService.queryObject(id);
        //判断越权行为
        if (!entity.getUserId().equals(loginUser.getUserId())) {
            return toResponsObject(403, "您无权删除", "");
        }
        addressService.delete(id);
        return toResponsSuccess("");
    }


    /**
     * 添加用户反馈
     */
    @ApiOperation(value = "添加用户反馈")
    @PostMapping("saveFeedback")
    public Object saveFeedback(@LoginUser UserVo loginUser, @RequestBody FeedbackVo feedbackVo) {
        feedbackVo.setUserId(loginUser.getUserId().intValue());
        feedbackVo.setUserName(loginUser.getNickname());
        feedbackVo.setAddTime(new Date());
        feedbackVo.setStatus(1);
        feedbackService.save(feedbackVo);
        return super.toResponsSuccess("感谢你的反馈");
    }

    /**
     * 上传文件
     */
    @ApiOperation(value = "上传文件")
    @IgnoreAuth
    @PostMapping("upload")
    public Object upload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        //上传文件
        String url = null;
        try {
            url = OSSFactory.build().upload(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return toResponsSuccess(url);
    }

    @ApiOperation(value = " 商品详情页数据")
    @GetMapping(value = "detailGoods")
    public Object detailGoods(@LoginUser UserVo loginUser,
                              @RequestParam("goodsId") Integer goodsId,
                              @RequestParam(value="promoterId", required = false) Long promoterId) {
        Map<String, Object> resultObj = new HashMap();
        //
        GoodsVo info = goodsService.queryObject(goodsId);

        info.setSource_price(info.getRetail_price());

        info.setRetail_price(ApiUserUtils.getActualPrice(loginUser, info));

        if(promoterId != null && promoterId > 0
                && !promoterId.equals(loginUser.getUserId())
                && loginUser.getUser_level_id() < 3){
            info.setPromoterId(promoterId);
            // 更新推荐人
            if(loginUser.getPromoterId() == null || loginUser.getPromoterId() == 0){
                Pair<UserVo, MlsUserEntity2> promoterUser = this.getUserObject(promoterId);
                if(promoterUser != null){
                    loginUser.setPromoterId(promoterId);
                    loginUser.setPromoterName(promoterUser.getKey().getNickname());

                    userService.update(loginUser);
                }
            }
        }

        Map param = new HashMap();
        param.put("goods_id", goodsId);
        //
        Map specificationParam = new HashMap();
        specificationParam.put("fields", "gs.*, s.name");
        specificationParam.put("goods_id", goodsId);
        specificationParam.put("specification", true);
        specificationParam.put("sidx", "s.sort_order");
        specificationParam.put("order", "asc");
        List<GoodsSpecificationVo> goodsSpecificationEntityList = goodsSpecificationService.queryList(specificationParam);

        List<Map> specificationList = new ArrayList();
        //按规格名称分组
        for (int i = 0; i < goodsSpecificationEntityList.size(); i++) {
            GoodsSpecificationVo specItem = goodsSpecificationEntityList.get(i);
            //
            List<GoodsSpecificationVo> tempList = null;
            for (int j = 0; j < specificationList.size(); j++) {
                if (specificationList.get(j).get("specification_id").equals(specItem.getSpecification_id())) {
                    tempList = (List<GoodsSpecificationVo>) specificationList.get(j).get("valueList");
                    break;
                }
            }
            //
            if (null == tempList) {
                Map temp = new HashMap();
                temp.put("specification_id", specItem.getSpecification_id());
                temp.put("name", specItem.getName());
                tempList = new ArrayList();
                tempList.add(specItem);
                temp.put("valueList", tempList);
                specificationList.add(temp);
            } else {
                for (int j = 0; j < specificationList.size(); j++) {
                    if (specificationList.get(j).get("specification_id").equals(specItem.getSpecification_id())) {
                        tempList = (List<GoodsSpecificationVo>) specificationList.get(j).get("valueList");
                        tempList.add(specItem);
                        break;
                    }
                }
            }
        }
        //
        List<GoodsGalleryVo> gallery = goodsGalleryService.queryList(param);
//        Map ngaParam = new HashMap();
//        ngaParam.put("fields", "nga.value, na.name");
//        ngaParam.put("sidx", "nga.id");
//        ngaParam.put("order", "asc");
//        ngaParam.put("goods_id", goodsId);
//        List<AttributeVo> attribute = attributeService.queryList(ngaParam);
        //
//        Map issueParam = new HashMap();
//        List<GoodsIssueVo> issue = goodsIssueService.queryList(issueParam);
        //
        BrandVo brand = brandService.queryObject(info.getBrand_id());
        //
        param.put("value_id", goodsId);
        param.put("type_id", 0);
        Integer commentCount = commentService.queryTotal(param);
        List<CommentVo> hotComment = commentService.queryList(param);
        Map commentInfo = new HashMap();
        if (null != hotComment && hotComment.size() > 0) {
            UserVo commentUser = userService.queryObject(hotComment.get(0).getUser_id());
            commentInfo.put("content", Base64.decode(hotComment.get(0).getContent()));
            commentInfo.put("add_time", DateUtils.timeToStr(hotComment.get(0).getAdd_time(), DateUtils.DATE_PATTERN));
            commentInfo.put("nickname", commentUser.getNickname());
            commentInfo.put("avatar", commentUser.getAvatar());
            Map paramPicture = new HashMap();
            paramPicture.put("comment_id", hotComment.get(0).getId());
            List<CommentPictureVo> commentPictureEntities = commentPictureService.queryList(paramPicture);
            commentInfo.put("pic_list", commentPictureEntities);
        }
        Map comment = new HashMap();
        comment.put("count", commentCount);
        comment.put("data", commentInfo);
        //当前用户是否收藏
        Map collectParam = new HashMap();
        collectParam.put("user_id", getUserId());
        collectParam.put("value_id", goodsId);
        collectParam.put("type_id", 0);
        Integer userHasCollect = collectService.queryTotal(collectParam);
        if (userHasCollect > 0) {
            userHasCollect = 1;
        }

        resultObj.put("info", info);
        resultObj.put("gallery", gallery);
//        resultObj.put("attribute", attribute);
        resultObj.put("userHasCollect", userHasCollect);
//        resultObj.put("issue", issue);
        resultObj.put("comment", comment);
        resultObj.put("brand", brand);
        resultObj.put("specificationList", specificationList);

        return toResponsSuccess(resultObj);
    }

    @ApiOperation(value = "新需求-百问百答，分页")
    @GetMapping("pageIssue")
    public Object pageIssue(@RequestParam(value = "page", defaultValue = "1") Integer page,
                               @RequestParam(value = "size", defaultValue = "10") Integer size,
                               @RequestParam(value = "question", required = false) String question) {
        Map issueParam = new HashMap();
        issueParam.put("page", page);
        issueParam.put("limit", size);
        if(StringUtils.isNotEmpty(question)){
            issueParam.put("question", "%"+question+"%");
        }

        Query query = new Query(issueParam);
        List<GoodsIssueVo> issueList = goodsIssueService.queryList(query);
        int total = goodsIssueService.queryTotal(query);
        ApiPageUtils pageUtil = new ApiPageUtils(issueList, total, query.getLimit(), query.getPage());
        return toResponsSuccess(pageUtil);
    }

    @Autowired
    private ApiTopicService topicService;
    @Autowired
    private ApiTopicCategoryMapper topicCategoryMapper;

    @ApiOperation(value = "新需求-选择素材类别")
    @GetMapping("selectTopicCategory")
    public Object selectTopicCategory() {
        return toResponsSuccess(topicCategoryMapper.queryList(null));
    }

    @ApiOperation(value = "新需求-素材，分页,content:素材名称；topicCategoryId：素材类别Id")
    @GetMapping("pageTopic")
    public Object pageTopic(@RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "size", defaultValue = "10") Integer size,
                            @RequestParam(value = "content", required = false) String content,
                            @RequestParam(value = "topicCategoryId", required = false) Integer topicCategoryId) {
        Map param = new HashMap();
        param.put("page", page);
        param.put("limit", size);
        param.put("content", content);
        param.put("topicCategoryId", topicCategoryId);
        param.put("fields", "id, content, item_pic_url, topic_category_id");
        //查询列表数据
        Query query = new Query(param);
        List<TopicVo> topicEntities = topicService.queryList(query);
        int total = topicService.queryTotal(query);
        ApiPageUtils pageUtil = new ApiPageUtils(topicEntities, total, query.getLimit(), query.getPage());
        return toResponsSuccess(pageUtil);
    }

    @ApiOperation(value = "新需求-素材详情")
    @GetMapping("detailTopic")
    public Object detailTopic(@RequestParam("id") Integer id) {
        TopicVo topicEntity = topicService.queryObject(id);
        return toResponsSuccess(topicEntity);
    }

    // 我的供货商
    @ApiOperation(value = "我的供货商，也即我的上级")
    @GetMapping("getFUser")
    public Object getFUser(@LoginUser UserVo loginUser) {
        MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
        if(fxUser != null) {
            MlsUserEntity2 FFxUser = mlsUserSer.getEntityMapper().getById(fxUser.getFid());
            if(FFxUser != null) {

                UserVo fUser = userService.queryObject(FFxUser.getUserId());

                return toResponsSuccess(fUser);
            }
        }
        return toResponsSuccess("您暂无供货商");
    }


    @ApiOperation(value = "获取所有的后代")
    @GetMapping("getAllSon")
    public Object getAllSon(@LoginUser UserVo loginUser,
                            @RequestParam(value = "page", defaultValue = "1") Integer page,
                            @RequestParam(value = "size", defaultValue = "100") Integer size,
                            @RequestParam(value="keywords", required = false) String keywords){
        IPage<UserVo> userPage = null;
        if(loginUser.getUser_level_id() >= 3){
            HashMap<String, Object> params = new HashMap<>();
            params.put("keywords", keywords);

            userPage = new Page<>(page, size);
            userPage = userService.getUserDao().getAllSon(userPage, params);

            if(CollectionUtils.isNotEmpty(userPage.getRecords())){
                for (UserVo userVo : userPage.getRecords()) {
                    userVo.setLevelName(ApiUserUtils.getLevelName(userVo.getUser_level_id()));
                    userVo.setUserId(userVo.getUserId() + ApiConstant.BASE_ID);

                    if(StringUtils.isEmpty(userVo.getRealName())){
                        userVo.setRealName(userVo.getNickname());
                    }
                }
            }
        }

        ApiPageUtils pageUtil = new ApiPageUtils(userPage == null ? null : userPage.getRecords(), userPage == null ?  0: new Long(userPage.getTotal()).intValue(), size, page);
        return toResponsSuccess(pageUtil);
    }

    @ApiOperation(value = "我的批发商管理，也即我的下级——分页接口")
    @GetMapping("getSonUser")
    public Object getSonUser(@LoginUser UserVo loginUser,
                             @RequestParam(value = "page", defaultValue = "1") Integer page,
                             @RequestParam(value = "size", defaultValue = "10") Integer size,
                             @RequestParam(value = "tmonth", required = false) String tmonth,
                             @RequestParam(value = "userNameOrMobile", required = false) String userNameOrMobile) {
        Map resultObj = new HashMap();

        MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
        if(fxUser != null) {

            HashMap<String, Object> params = new HashMap<>();
            params.put("fid", fxUser.getMlsUserId());

            int addUserWeek = userService.getUserDao().addUserWeek(params);
            int addUserMonth = userService.getUserDao().addUserMonth(params);
            int addUserAll = userService.getUserDao().addUserAll(params);
            resultObj.put("addUserWeek", addUserWeek);
            resultObj.put("addUserMonth", addUserMonth);
            resultObj.put("allUser", addUserAll);

            Long userId = 0L;
            try{
                if(userNameOrMobile.startsWith("5")){
                    userId = Long.parseLong(userNameOrMobile);
                    if(userId > ApiConstant.BASE_ID){
                        userId -= ApiConstant.BASE_ID;
                        userNameOrMobile = userId.toString();
                    }
                }
            }catch (Exception e){
            }

            params.put("userNameOrMobile", userNameOrMobile);
            params.put("tmonth", tmonth);

            IPage<UserVo> userPage = new Page<>(page, size);
            userPage = userService.getUserDao().findSons(userPage, params);

            List<UserVo> userVoList = userPage.getRecords();



            for(UserVo user : userVoList){

                List<SonGoods> sonGoodsList = userService.getUserDao().findSonGoods(user.getMlsUserId());

                // 最终统计的结果
                Map<Integer, SonGoods> sumSonGoodsMap = new HashMap<>();

                if(CollectionUtils.isNotEmpty(sonGoodsList)){
                    // 获取所有单品
                    Map<String, Object> map = new HashMap<>();
                    map.put("is_secKill", 1);
                    List<GoodsVo> goodsVos = goodsService.queryList(map);

                    Map<Integer, GoodsVo> goodsVoMap = goodsVos.stream().collect(Collectors.toMap(GoodsVo::getId, Function.identity()));


                    Map<Integer, SonGoods> sonGoodsVoMap = sonGoodsList.stream().collect(Collectors.toMap(SonGoods::getGoodsId, Function.identity()));

                    for(Map.Entry<Integer, SonGoods> entry : sonGoodsVoMap.entrySet()){
                        SonGoods sonGoods = entry.getValue();
                        if(sonGoods.getIs_secKill() == 1){// 单品
                            sumSonGoodsMap.put(entry.getKey(), entry.getValue());// 直接用数据库的覆盖
                        }else if(sonGoods.getIs_secKill() == 4){// 套餐
                            String[] relGoods = sonGoods.getRelGoodsId().split(";");
                            for(String goods : relGoods){
                                // 1:4;4:8,表示id=1，单品4个；
                                String[] goodsArr =  goods.split(":");
                                Integer goodsId = Integer.parseInt(goodsArr[0]);
                                Integer goodsNum = Integer.parseInt(goodsArr[1]);
                                if(sumSonGoodsMap.containsKey(goodsId)){
                                    SonGoods sonGoods1 = sumSonGoodsMap.get(goodsId);

                                    sonGoods1.setAllNum(sonGoods1.getAllNum() + sonGoods.getAllNum() * goodsNum);
                                    sonGoods1.setMonthNum(sonGoods1.getMonthNum() + sonGoods.getMonthNum() * goodsNum);

                                    sumSonGoodsMap.put(goodsId, sonGoods1);
                                }else{
                                    // 新建
                                    SonGoods newSonGoods = new SonGoods();
                                    newSonGoods.setGoodsId(goodsId);
                                    newSonGoods.setMonthNum(sonGoods.getMonthNum() * goodsNum);
                                    newSonGoods.setAllNum(sonGoods.getAllNum() * goodsNum);

                                    GoodsVo goodsVo = goodsVoMap.get(goodsId);
                                    if(goodsVo != null){
                                        newSonGoods.setGoodsName(goodsVo.getName());
                                    }else{
                                        newSonGoods.setGoodsName("该产品已下架，id："+goodsId);
                                    }

                                    newSonGoods.setIs_secKill(1);

                                    sumSonGoodsMap.put(goodsId, newSonGoods);
                                }

                            }
                        }

                    }
                    // 删除非单品
                    sumSonGoodsMap.values().removeIf(value -> value.getIs_secKill() != 1);
                }
                user.setSonGoodsList(sumSonGoodsMap.values().stream().collect(Collectors.toList()));
            }

            ApiPageUtils pageUtil = new ApiPageUtils(userPage.getRecords(), new Long(userPage.getTotal()).intValue(), size, page);

            resultObj.put("sonUserList", pageUtil);

        }
        return toResponsSuccess(resultObj);
    }

    @ApiOperation(value = "我的平级经销商——他的推荐人是你，并且和你平级，不分页")
    @GetMapping("getSameUser")
    public Object getSameUser(@LoginUser UserVo loginUser,
                                  @RequestParam(value="userNameOrMobile",required = false) String userNameOrMobile) {
        Map<String , Object> param = new HashMap<>();
        param.put("promoterId", loginUser.getUserId());
        param.put("userNameOrMobile", userNameOrMobile);
        param.put("userLevelId", loginUser.getUser_level_id());
        List<UserVo> promoterList =  userService.queryList(param);

        Map resultObj = new HashMap();

        int addUserWeek = 0, addUserMonth = 0, addUserAll = 0;
        if(CollectionUtils.isNotEmpty(promoterList)){
            addUserAll = promoterList.size();
            for(UserVo user : promoterList){
                if(user.getRegister_time().after(DateUtils.getTimesWeekmorning())){
                    addUserWeek++;
                }
                if(user.getRegister_time().after(DateUtils.getTimesMonthmorning())){
                    addUserMonth++;
                }
            }
        }

        resultObj.put("promoterList", promoterList);
        resultObj.put("addUserWeek", addUserWeek);
        resultObj.put("addUserMonth", addUserMonth);
        resultObj.put("allUser", addUserAll);

        return toResponsSuccess(resultObj);
    }

    @ApiOperation(value = "我的会员管理，也即我推广的人")
    @GetMapping("getPromoterList")
    public Object getPromoterList(@LoginUser UserVo loginUser,
                                  @RequestParam(value="userNameOrMobile",required = false) String userNameOrMobile,
                                  @RequestParam(value="userLevelId") Integer userLevelId) {

        if(userLevelId != 1 && userLevelId != 2){
            return toResponsFail("只能查询访客或者VIP");
        }

        Map<String , Object> param = new HashMap<>();
        param.put("promoterId", loginUser.getUserId());
        param.put("userNameOrMobile", userNameOrMobile);
        param.put("userOrVip", 1);
        List<UserVo> promoterList =  userService.queryList(param);

        Map resultObj = new HashMap();

        List<UserVo> promoterList2 = new ArrayList<>();

        int addUserWeek = 0, addUserMonth = 0;
        if(CollectionUtils.isNotEmpty(promoterList)){
            for(UserVo user : promoterList){

                if(userLevelId != null && user.getUser_level_id() == userLevelId){
                    promoterList2.add(user);
                }

                if(user.getRegister_time().after(DateUtils.getTimesWeekmorning())){
                    addUserWeek++;
                }
                if(user.getRegister_time().after(DateUtils.getTimesMonthmorning())){
                    addUserMonth++;
                }
            }
        }

        resultObj.put("promoterList", promoterList2);

        resultObj.put("addUserWeek", addUserWeek);
        resultObj.put("addUserMonth", addUserMonth);

        return toResponsSuccess(resultObj);
    }

    @ApiOperation(value = "可用余额")
    @GetMapping("getMlsUser")
    public Object getMlsUser(@LoginUser UserVo loginUser) {
        MlsUserEntity2 fxUser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
        if(fxUser != null) {
            if(fxUser!=null) {
                return toResponsSuccess(fxUser);
            }
        }
        return toResponsMsgSuccess("未找到关联分销用户");
    }

    @ApiOperation(value = "商品二维码图片")
    @GetMapping("getGoodCode")
    public Object getGoodCode(@LoginUser UserVo loginUser, @RequestParam("goodId") Integer goodId) {
        String qrCode = this.getUserId() + goodId + ".png";//文件名称
        String returnUrl = "goodscode/"+ this.getUserId()+ "/" + qrCode;//返回路径

        String key = "goodscode:"+loginUser.getUserId()+":"+ qrCode;
        if(RedisUtils.exists(key)){
            return toResponsSuccess(RedisUtils.get(key));
        }

        InputStream baseStream = this.getClass().getClassLoader().getResourceAsStream("data/base.png");

        //获取商品主图和2张配图
        GoodsVo goods = goodsService.queryObject(goodId);
        String p1 = goods.getList_pic_url();//主图

        //获取logo
        BrandVo brand = brandService.queryObject(goods.getBrand_id());
        String p4 = brand.getList_pic_url();

        String goodsUrl = null;
        try {
            String content = ApiUserUtils.getREDIRECT_URI(request, "/shop/goods/info/id/goodInfo.html?goodsId="+goodId+"&promoterId="+this.getUserId());
            logger.info("》》》商品二维码:{}", content);
            BufferedImage qrcodeImage = QRCodeUtil.createImage(content, null, true);

            BufferedImage newImage = ImageUtils.coverImage(ImageIO.read(baseStream), ImageIO.read(new URL(p1)), 180, 306, 645, 645);
            newImage = ImageUtils.coverImage(newImage, ImageIO.read(new URL(p4)), 50, 50, 125, 125);
            newImage = ImageUtils.coverImage(newImage, qrcodeImage, 48, 1025, 200, 200);
            newImage = ImageUtils.coverText(newImage, brand.getName(), 220, 100,new Font("宋体",Font.BOLD,40),Color.black);
            newImage = ImageUtils.coverText(newImage, goods.getName(), 53, 240,new Font("宋体",Font.BOLD,40),Color.gray);
            newImage = ImageUtils.coverText(newImage, "请在微信长按识别二维码选购商品", 280, 1180,new Font("宋体",Font.BOLD,18),Color.lightGray);

            goodsUrl = OSSFactory.build().upload(QRCodeUtil.imageToBytes(newImage), returnUrl);
            RedisUtils.set(key, goodsUrl);
        } catch (Exception e) {
            logger.error("二维码生成失败",e);
            return toResponsFail("二维码生成失败");
        }
        return toResponsSuccess(goodsUrl);
    }

    @ApiOperation(value = "我的推广码")
    @GetMapping("getUserQrCode")
    public Object getUserQrCode(@LoginUser UserVo loginUser) {

        if(StringUtils.isNotBlank(loginUser.getQrCode())){
            return toResponsSuccess(loginUser.getQrCode());
        }

        String qrCodeUrl = null;
        try {
            String content = ApiUserUtils.getREDIRECT_URI(request, "/index.html?promoterId="+this.getUserId());
            logger.info("》》》我的推广码:{}", content);
            // 推广码
            BufferedImage qrcode = QRCodeUtil.createImage(content, loginUser.getAvatar(), true);
            // 底图
            InputStream baseStream = this.getClass().getClassLoader().getResourceAsStream("data/userbasenew3.jpg");
            // 合成新图
            BufferedImage newImage = ImageUtils.coverImage(ImageIO.read(baseStream), qrcode, 678, 1681, 230, 230);

            qrCodeUrl = OSSFactory.build().upload(QRCodeUtil.imageToBytes(newImage), "userqrcode/" + loginUser.getUserId()+"_userbasenew3.jpg");

            loginUser.setQrCode(qrCodeUrl);
            userService.update(loginUser);

        } catch (Exception e) {
            logger.error("二维码生成失败",e);
            return toResponsFail("二维码生成失败");
        }

        return toResponsSuccess(qrCodeUrl);
    }

    @Autowired
    private ApiGoodsQrcodeMapper apiGoodsQrcodeMapper;

    @Autowired
    private ApiGoodsQrcodeScanMapper apiGoodsQrcodeScanMapper;

    @IgnoreAuth
    @ApiOperation(value = "防伪码扫码")
    @GetMapping("securityCodeScan")
    public Object securityCodeScan(HttpServletRequest request, @RequestParam("securityCode") String securityCode) {
        Map resultObj = new HashMap();

        // 判断防伪码是否有效
        QueryWrapper<GoodsQrcodeVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("security_code", securityCode);

        GoodsQrcodeVo goodsQrcodeVo = apiGoodsQrcodeMapper.selectOne(queryWrapper);
        if(goodsQrcodeVo == null){
            return toResponsFail("非法二维码");
        }

        GoodsVo goodsVo = goodsService.queryObject(goodsQrcodeVo.getGoodsId());

        // 获取上次的扫码数据
        String ipKey = "lastScan:"+securityCode+":ip";
        String timeKey = "lastScan:"+securityCode+":time";
        goodsQrcodeVo.setLastScanIp(RedisUtils.get(ipKey));
        goodsQrcodeVo.setLastScanTime(DateUtils.strToDate(RedisUtils.get(timeKey)) );

        // 新增一笔扫码记录
        GoodsQrcodeScanVo goodsQrcodeScanVo = new GoodsQrcodeScanVo();
        goodsQrcodeScanVo.setQrcodeId(goodsQrcodeVo.getId());
        goodsQrcodeScanVo.setScanIp(RequestUtil.getIpAddrByRequest(request));
        goodsQrcodeScanVo.setScanTime(new Date());

        apiGoodsQrcodeScanMapper.insert(goodsQrcodeScanVo);

        //  更新上次的扫码数据
        RedisUtils.set(ipKey, goodsQrcodeScanVo.getScanIp());
        RedisUtils.set(timeKey, DateUtils.format(goodsQrcodeScanVo.getScanTime(), DateUtils.DATE_TIME_PATTERN) );

        //修改当前扫码记录
        goodsQrcodeVo.setScanCount((goodsQrcodeVo.getScanCount() == null ? 0: goodsQrcodeVo.getScanCount()) + 1);
        apiGoodsQrcodeMapper.updateById(goodsQrcodeVo);

        resultObj.put("goodsVo", goodsVo);
        resultObj.put("goodsQrcodeVo", goodsQrcodeVo);

        return toResponsSuccess(resultObj);
    }

    @ApiOperation(value = "获取合同模板", response = Map.class)
    @GetMapping("listContractTpl")
    public Object listContractTpl() {
        QueryWrapper<ContractTplVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("sort_order");

        List<ContractTplVo> contractTplVoList = apiContractTplMapper.selectList(queryWrapper);

        return toResponsSuccess(contractTplVoList);
    }

    @ApiOperation(value = "分页获取合同", response = Map.class)
    @GetMapping("pageContract")
    public Object pageContract(@LoginUser UserVo loginUser, @RequestParam(value = "page", defaultValue = "1") Integer page,
                               @RequestParam(value = "size", defaultValue = "10") Integer size,
                               @RequestParam(value = "status", required = false) Integer status) {
        IPage<ContractVo> contractPage = new Page<>(page, size);

        QueryWrapper<ContractVo> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq(status != null && status < 4, "status", status);
        queryWrapper.lt(status != null && status == 4, "end_time", new Date());

        queryWrapper
                .and(wrapper -> wrapper
                        .eq("send_user_id", loginUser.getUserId())
                        .or()
                        .eq("recv_user_id", loginUser.getUserId()));

        queryWrapper.orderByDesc("id");

        contractPage = apiContractMapper.selectPage(contractPage, queryWrapper);

        List<ContractVo> contractVoList =  contractPage.getRecords();
        if(CollectionUtils.isNotEmpty(contractVoList)){
            for(ContractVo vo : contractVoList){
                handleContractVo(loginUser, vo);
            }
        }

        ApiPageUtils pageUtil = new ApiPageUtils(contractPage.getRecords(), new Long(contractPage.getTotal()).intValue(), size, page);

        return toResponsSuccess(pageUtil);
    }

    private void handleContractVo(UserVo loginUser, ContractVo vo) {
        UserVo userVo = userService.queryObject(vo.getSendUserId());
        if(userVo != null){
            vo.setSendUserName(userVo.getRealName());
        }

        UserVo userVo2 = userService.queryObject(vo.getRecvUserId());
        if(userVo2 != null){
            vo.setRecvUserName(userVo2.getRealName());
        }

        vo.setEnableSign(0);

        // 当前用户是发起人，合同状态是待甲方签署，则允许
        if(userVo != null && loginUser.getUserId().equals(vo.getSendUserId()) && vo.getStatus() == 1){
            vo.setEnableSign(1);
        }

        // 当前用户是接收人，合同状态是待乙方签署，则允许
        if(userVo2 != null && loginUser.getUserId().equals(vo.getRecvUserId()) && vo.getStatus() == 2){
            vo.setEnableSign(1);
        }
    }

    @ApiOperation(value = "获取合同详情", response = Map.class)
    @GetMapping("detailContract")
    public Object detailContract(@LoginUser UserVo loginUser, @RequestParam(value = "contractId") Long contractId) {
        ContractVo contractVo = apiContractMapper.selectById(contractId);

        handleContractVo(loginUser, contractVo);

        ContractTplVo contractTplVo = apiContractTplMapper.selectById(contractVo.getTplId());
        contractVo.setTplUrl(contractTplVo.getTplUrl());

        return toResponsSuccess(contractVo);
    }

    @ApiOperation(value = "发起合同", response = Map.class)
    @PostMapping("sendContract")
    public Object sendContract(@LoginUser UserVo loginUser, @RequestBody ContractVo entity) {

        if(entity.getRecvUserId() == null){
            return toResponsFail("接收人id不能为空");
        }

        if(loginUser.getUser_level_id() <=3 ){
            return toResponsFail("代理级别不够，不发起合同");
        }

        Long id = entity.getRecvUserId();
        if(id > ApiConstant.BASE_ID){
            id -= ApiConstant.BASE_ID;
        }

        UserVo userVo = userService.queryObject(id);
        if(userVo == null){
            return toResponsFail("乙方用户ID["+id+"]不存在");
        }

        if(userVo != null && loginUser.getUser_level_id() <= userVo.getUser_level_id() ){
            return toResponsFail("发起人代理级别不够，不能发起合同");
        }

        entity.setId(null);// 新增
        entity.setStatus(1);// 待我签

        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 7);
        entity.setEndTime(c.getTime());

        entity.setSendUserId(loginUser.getUserId());

        entity.setRecvUserId(id);
        
        apiContractMapper.insert(entity);

        return toResponsSuccess("发起合同成功");
    }

    @ApiOperation(value = "合同签名", response = Map.class)
    @PostMapping("signContract")
    public Object signContract(@LoginUser UserVo loginUser, @RequestParam("contractId")Long contractId, @RequestParam("sign")String sign, @RequestParam("status")Integer status) {

        ContractVo contractVo = apiContractMapper.selectById(contractId);
        if(contractVo == null){
            return toResponsFail("合同id"+contractId+"不存在");
        }

        if(status > 2){
            return toResponsFail("合同已完成或者已过期");
        }

        // 1：待我签；2：待他签；3：已完成；4：已过期
        if(status == 1){
            contractVo.setSendSign(sign);
            contractVo.setSendTime(new Date());
            contractVo.setStatus(2);
            apiContractMapper.updateById(contractVo);
        }else if(status == 2){
            contractVo.setRecvSign(sign);
            contractVo.setRecvTime(new Date());
            contractVo.setStatus(3);
            apiContractMapper.updateById(contractVo);
        }
        return toResponsSuccess("合同签名成功");
    }

    @ApiOperation(value = "获取资金明细——修改为分页接口，交易类型（types）：1后台调整、2分润、3余额支付、4提现、5微信支付", response = Map.class)
    @GetMapping("getAmountDetial")
    public Object getAmountDetial(@LoginUser UserVo loginUser,
                                  @RequestParam(value = "page", defaultValue = "1") Integer page,
                                  @RequestParam(value = "size", defaultValue = "10") Integer size,
                                  @RequestParam(value = "tmonth", required = false) String tmonth,
                                  @RequestParam(value = "types", required = false) Integer types,
                                  @RequestParam(value = "direction", required = false) Integer direction) {
        Map<String, Object> resultObj = new HashMap();

        HashMap<String, Object> params = new HashMap<>();
        params.put("tmonth", tmonth);
        params.put("userId", loginUser.getUserId());
        Map<String, Object> totalList = userRecordSer.getEntityMapper().getAmountSummary(params);
        resultObj.put("total", totalList);

        params.put("types", types);
        params.put("direction", direction);
        IPage<UserRecord> userRecordPage = new Page<>(page, size);
        userRecordPage = userRecordSer.getEntityMapper().getAmountDetail(userRecordPage, params);
        ApiPageUtils pageUtil = new ApiPageUtils(userRecordPage.getRecords(), new Long(userRecordPage.getTotal()).intValue(), size, page);
        resultObj.put("userRecordList", pageUtil);

        return toResponsSuccess(resultObj);
    }

    @ApiOperation(value = "获取资金报表——修改为分页接口，资金方向必传，收入：1；支出：-1；提现：types=4,direction=-1", response = Map.class)
    @GetMapping("getAmountReport")
    public Object getAmountReport(@LoginUser UserVo loginUser,
                                  @RequestParam(value = "page", defaultValue = "1") Integer page,
                                  @RequestParam(value = "size", defaultValue = "10") Integer size,
                                  @RequestParam(value = "tmonth", required = false) String tmonth,
                                  @RequestParam(value = "types", required = false) Integer types,
                                  @RequestParam(value = "direction") Integer direction) {
        // 收入：1；支出：-1；提现：types=4,direction=-1
        return getAmountDetial(loginUser, page, size, tmonth, types, direction);
    }

    @ApiOperation(value = "获取柱状图", response = Map.class)
    @GetMapping("getBar")
    public Object getAmountReport(@LoginUser UserVo loginUser,
                                  @RequestParam(value = "types", required = false) Integer types,
                                  @RequestParam(value = "direction") Integer direction) {
        Map<String, Object> resultObj = new HashMap();

        // 收入：1；支出：-1；提现：types=4,direction=-1

        HashMap<String, Object> params = new HashMap<>();
        params.put("userId", loginUser.getUserId());
        params.put("types", types);
        params.put("direction", direction);

        List<String> monthList = new ArrayList<>();
        for(int i = 5; i >= 0; i--){
            Calendar c = Calendar.getInstance();
            c.add(Calendar.MONTH, -i);
            monthList.add(DateUtils.format(c.getTime(), "MM") + "月");
        }

        resultObj.put("monthList", monthList);

        Map<String, Object> monthAmount = userRecordSer.getEntityMapper().getAmountMonth(params);
        List<Object> amountList = new ArrayList<>();
        if(monthAmount == null || monthAmount.size() == 0){
            amountList.add(0);
            amountList.add(0);
            amountList.add(0);
            amountList.add(0);
            amountList.add(0);
            amountList.add(0);
        }else{
            amountList.add(monthAmount.get("m1"));
            amountList.add(monthAmount.get("m2"));
            amountList.add(monthAmount.get("m3"));
            amountList.add(monthAmount.get("m4"));
            amountList.add(monthAmount.get("m5"));
            amountList.add(monthAmount.get("m6"));
        }
        resultObj.put("amountList", amountList);
        return toResponsSuccess(resultObj);
    }

    @Autowired
    private ApiUserLevelMapper apiUserLevelMapper;

    @GetMapping("/selectProxyLevel")
    @ApiOperation(value = "选择代理等级")
    public Object selectProxyLevel(@LoginUser UserVo loginUser) {

        Map<String, Object> resultObj = new HashMap();
        if(loginUser.getUser_level_id() < 3){
            return toResponsFail("没有可设置的代理等级");
        }

        QueryWrapper<UserLevelVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("id", 2);
        queryWrapper.lt("id", loginUser.getUser_level_id());
        queryWrapper.orderByAsc("id");

        List<UserLevelVo> userLevelVoList = apiUserLevelMapper.selectList(queryWrapper);

        return toResponsSuccess(userLevelVoList);
    }

    /**
     * 如果当前会员A从游客或者vip升级到代理，需要将A推荐的非代理级别的会员X绑定到A名下，
     * 后续X购买产生的分润归A
     *
     * 寻找A推荐的会员X逻辑：
     * 1、推荐人是A但上级不是A，并且会员X没有代理身份，
     * 可能存在A->x1->x3->x4，x3先于A升级了代理，此时只要绑定x1,x2的上级为A
     *        ->x2
     * 2、getFuns(promoterId)-->递归调用获取推荐人的粉丝，
     * 3、将粉丝X的原来上级更新为A
     * 直到推荐人没有粉丝或者推荐人的粉丝是代理商为止
     * @param promoterId
     * @return
     */
    private List<UserVo> getFuns(Long promoterId){

        List<UserVo> funsUser = new ArrayList<>();
        // 获取推荐人推荐的所有粉丝（只包含游客和vip）
        Map<String , Object> param = new HashMap<>();
        param.put("promoterId", promoterId);
        param.put("userOrVip", 1);
        List<UserVo> promoterList =  userService.queryList(param);
        if(CollectionUtils.isNotEmpty(promoterList)){
            promoterList.stream().forEach(promoter -> {
                // 找到放到集合中
                funsUser.add(promoter);
                // 继续粉丝推荐的粉丝
                funsUser.addAll(getFuns(promoter.getUserId()));
            });
        }
        return funsUser;
    }

    /**
     * @param loginUser
     * @param id
     * @param userLevelId
     * @return
     */
    @GetMapping("/setProxyLevel")
    @ApiOperation(value = "设定代理身份")
    public Object setProxyLevel(@LoginUser UserVo loginUser, @RequestParam("id") Long id, @RequestParam("userLevelId") Integer userLevelId) {

        if(id > ApiConstant.BASE_ID){
            id -= ApiConstant.BASE_ID;
        }

        UserVo user = userService.queryObject(id);
        if(user == null){
            return toResponsFail("会员id"+id+"不存在");
        }

        MlsUserEntity2 newUser = mlsUserSer.getEntityMapper().findByUserId(user.getUserId());
        if(newUser == null){
            return toResponsFail("会员id"+id+"不存在分销用户");
        }

        if(user.getUser_level_id() != null){//
            if(userLevelId.equals(user.getUser_level_id())){
                return toResponsFail("同级别不能再次设定");
            }else if(userLevelId < user.getUser_level_id()){
                return toResponsFail("只能提升代理级别");
            }

            if(userLevelId >= 3){
                // 13 健康卫士合同模板  --- 3 userLevelId
                // 14 健康管家合同模板  --- 4 userLevelId
                // 15 健康大使合同模板  --- 5 userLevelId
                Map<Integer, Integer> userLevelTplMap = new HashMap<>();
                userLevelTplMap.put(3, 13);
                userLevelTplMap.put(4, 14);
                userLevelTplMap.put(5, 15);

                // 是否已经签订合同
                QueryWrapper<ContractVo> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("tpl_id", userLevelTplMap.get(userLevelId));
                queryWrapper.eq("send_user_id", loginUser.getUserId());
                queryWrapper.eq("recv_user_id", id);
                queryWrapper.eq("status", 3); // 已完成
                Integer count = apiContractMapper.selectCount(queryWrapper);
                if(count == null || count < 1){
                    return toResponsFail("请先与经销商签订合同再设定代理身份");
                }
            }
        }
        Integer oldUserLevelId = user.getUser_level_id();
        user.setUser_level_id(userLevelId);
        userService.update(user);

        MlsUserEntity2 mlsuser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
        newUser.setFid(mlsuser.getMlsUserId());
        mlsUserSer.getEntityMapper().updateFid(newUser);

        if(oldUserLevelId < 3 && userLevelId >= 3){
            List<UserVo> funsUser = getFuns(user.getUserId());
            if(CollectionUtils.isNotEmpty(funsUser)){
                log.info("该会员id：{}-{}, 分销id：{}，原上级分销id：{}",
                        user.getUserId(),user.getNickname(),newUser.getMlsUserId(),newUser.getFid());
                List<Long> funsUserId = new ArrayList<>();
                funsUser.stream().forEach(funUser -> {
                    funsUserId.add(funUser.getUserId());
                    log.info("他的的粉丝会员id：{}-{}；推荐人id：{}-{}",
                            funUser.getUserId(), funUser.getNickname(), funUser.getPromoterId(), funUser.getPromoterName());
                });
                mlsUserSer.getEntityMapper().updateFidBatch(newUser.getMlsUserId(), funsUserId.toArray());
            }
        }

        return toResponsSuccess(newUser);
    }

    @Autowired
    private ApiActivitySignService apiActivitySignService;

    /**
     * 设定活动名额
     * @param loginUser
     * @param id
     * @return
     */
    @GetMapping("/setActivitySign")
    @ApiOperation(value = "设定活动名额")
    public Object setActivitySign(@LoginUser UserVo loginUser, @APPLoginUser MlsUserEntity2 fxUser, @RequestParam("id") Long id) {
        if(id > ApiConstant.BASE_ID){
            id -= ApiConstant.BASE_ID;
        }

        UserVo user = userService.queryObject(id);
        if(user == null){
            return toResponsFail("会员id"+id+"不存在");
        }

        // 判断该用户是否当前用户的会员
        MlsUserEntity2 mlsUser = mlsUserSer.getEntityMapper().findSonByFid(id, fxUser.getMlsUserId());
        if(mlsUser == null){
            return toResponsFail("会员id"+id+"不属于您的会员");
        }

        // 判断之前是否已参加过活动
        ActivitySign activitySign = apiActivitySignService.getActivitySigned(loginUser.getUserId(), id);
        if(activitySign != null){
            return toResponsFail("会员id"+id+"已被设定活动名额");
        }
        // 保存活动信息
        ActivitySign newActivity = new ActivitySign();
        newActivity.setSendTime(new Date());
        newActivity.setSendUserId(loginUser.getUserId());
        newActivity.setRecvUserId(id);
        newActivity.setStatus(1);// 默认为未参与
        apiActivitySignService.save(newActivity);

        return toResponsSuccess(user);
    }

    /**
     * VIP和VIP以上可以发起
     * 不能申请成为战略，门店-总代-大区
     * @param loginUser
     * @return
     */
    @GetMapping("/selectApplyForLevel")
    @ApiOperation(value = "发起申请的代理级别")
    public Object selectApplyForLevel(@LoginUser UserVo loginUser) {
        Map<String, Object> resultObj = new HashMap();

        QueryWrapper<UserLevelVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("id", loginUser.getUser_level_id() < 3 ? 2 : loginUser.getUser_level_id())
        .ne("id", 6);
        queryWrapper.orderByAsc("id");

        List<UserLevelVo> userLevelVoList = apiUserLevelMapper.selectList(queryWrapper);

        return toResponsSuccess(userLevelVoList);
    }

    @Value("${weixin.mp.platOpenId}")
    private String platOpenId;

    @GetMapping("/sendApplyFor")
    @ApiOperation(value = "发起申请")
    public Object sendApplyFor(@LoginUser UserVo loginUser, @RequestParam("userLevelId") Integer userLevelId) {
        if(userLevelId == 1 || userLevelId == 2 || userLevelId == 6){
            return toResponsFail("申请级别不能是"+ApiUserUtils.getLevelName(userLevelId)+"，不能发起申请");
        }
//        {{first.DATA}}
//        申请人姓名：{{keyword1.DATA}}
//        申请人账号：{{keyword2.DATA}}
//        申请人ID：{{keyword3.DATA}}
//        申请人电话：{{keyword4.DATA}}
//        审核时效：{{keyword5.DATA}}
//        {{remark.DATA}}

//        来自XXX的健康大使的经销商申请，注意查收
//        申请人姓名：张先生
//        申请人账号：XXX
//        申请人ID：5000123
//        申请人电话：158****3573
//        审核时效：2020-03-08
//        请在经销商申请七日内审核经销商资格，并联系申请人签订经销商协议

        String first = "来自"+ApiUserUtils.getLevelName(loginUser.getUser_level_id())+"-"+loginUser.getRealName()+"的"+ApiUserUtils.getLevelName(userLevelId)+"的经销商申请，注意查收";
        String remark = "请在经销商申请七日内审核经销商资格，并联系申请人签订经销商协议";

        List<String> keywords = new ArrayList<>();
        keywords.add(loginUser.getRealName());
        keywords.add(loginUser.getNickname());
        Long id = loginUser.getUserId() + ApiConstant.BASE_ID;
        keywords.add(id.toString());
        keywords.add(loginUser.getMobile());

        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 7);
        keywords.add(DateUtils.format(c.getTime(), "yyyy-MM-dd"));

        // 申请需要公众号消息或者短信通知到上上级，并抄送到推荐人和上级
        Pair<UserVo, MlsUserEntity2> curUser = this.getUserObject(loginUser.getUserId());

        Pair<UserVo, MlsUserEntity2> promoterUser = this.getUserObject(curUser.getKey().getPromoterId());
        if(promoterUser != null){
            this.sendMsg(promoterUser.getKey().getWeixin_openid(), ApiConstant.MP_TEMPLATE_ID_APPLY, first, remark, keywords);
        }

        Pair<UserVo, MlsUserEntity2> fidUser = this.getFidUserObject(curUser.getValue().getFid());
        if(fidUser != null){
            this.sendMsg(fidUser.getKey().getWeixin_openid(), ApiConstant.MP_TEMPLATE_ID_APPLY, first, remark, keywords);

            // 如果上级级别比申请的级别低，则要发送到上上级
//            if(fidUser.getKey().getUser_level_id() <= userLevelId){
//                Pair<UserVo, MlsUserEntity2> fidFidUser = null;
//                fidFidUser = this.getFidUserObject(fidUser.getValue().getFid());
//                if(fidFidUser != null){
//                    this.sendMsg(fidFidUser.getKey().getWeixin_openid(), ApiConstant.MP_TEMPLATE_ID_APPLY, first, remark, keywords);
//                }else{
//                    this.sendMsg(platOpenId, ApiConstant.MP_TEMPLATE_ID_APPLY, first, remark, keywords);
//                }
//            }
        }else{
            this.sendMsg(platOpenId, ApiConstant.MP_TEMPLATE_ID_APPLY, first, remark, keywords);
        }

        return toResponsSuccess("发起申请成功");
    }

    private void sendMsg(String openId, String templateId, String first, String remark, List<String> keywords){
        // 给上上级发送消息提醒
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", openId);
        jsonObject.put("template_id", templateId);

        JSONObject data = new JSONObject();
        JSONObject firstObj = new JSONObject();
        firstObj.put("value", first);
        data.put("first", firstObj);

        if(CollectionUtils.isNotEmpty(keywords)){
            for(int i = 1; i <= keywords.size(); i++){
                JSONObject keyword = new JSONObject();
                keyword.put("value", keywords.get(i-1));
                data.put("keyword"+i, keyword);
            }
        }

        JSONObject remarkObj = new JSONObject();
        remarkObj.put("value", remark);
        data.put("remark", remarkObj);

        jsonObject.put("data", data);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
        HttpEntity<String> strEntity = new HttpEntity<String>(jsonObject.toJSONString(), headers);

        String accessToken = tokenService.getAccessToken();
        logger.info("》》》weixin access token为：" + accessToken);
        String res = restTemplate.postForObject(ApiUserUtils.getTemplateMsgUrl(accessToken), strEntity, String.class);
        log.info("TemplateMsgUrl res:{}", res);
    }


    @ApiOperation(value = "用户提现")
    @PostMapping("withdrawCashes")
    public Object withdrawCashes(@LoginUser UserVo loginUser, @RequestParam("amount") Double amount) {
        String name = loginUser.getRealName();
        if(StringUtils.isBlank(name)) {
            return toResponsFail("真实姓名为空");
        }
        if(amount == null || amount == 0) {
            return toResponsFail("提现金额为空");
        }

        MlsUserEntity2 mlsuser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
        //系统设置的最小提现金额
        String txMin = mlsUserSer.getEntityMapper().queryByKey("tx_min");
        if(StringUtils.isNotBlank(txMin)) {
            int min = new Integer(txMin);
            if(min > amount) {
                return toResponsFail("最小提现金额为"+min);
            }
        }

        if(mlsuser.getAllProfit().intValue() < new Double(amount).intValue()) {
            return toResponsFail("超出可用余额");
        }

        // 扣除税费 7%
        BigDecimal amountSrc = new BigDecimal(amount).setScale(0,   BigDecimal.ROUND_HALF_UP);
        BigDecimal taxVal = amountSrc.multiply(new BigDecimal("0.07")).setScale(0,   BigDecimal.ROUND_HALF_UP);

        BigDecimal amountVal = amountSrc.subtract(taxVal).setScale(0,   BigDecimal.ROUND_HALF_UP);

        //设置提现redis锁，当成功删除key
        String txKey = RedisUtils.get("tx"+mlsuser.getMlsUserId());
        if(StringUtils.isNotBlank(txKey)) {
            return toResponsFail("当前提现没有完成，也可以联系管理员。");
        }
        try{
            //设置redisKsy
            RedisUtils.set("tx"+mlsuser.getMlsUserId(), "10");

            //插入提现记录表
            UserRecord newur = new UserRecord();
            newur.setMlsUserId(mlsuser.getMlsUserId());
            newur.setTypes(4);
            newur.setTypesStr("提现");
            newur.setPrice(amountSrc.intValue());
            newur.setRemarks("提现金额:"+amountSrc.intValue()+"，实际可到账："+amountVal.intValue()+"，税费："+taxVal.intValue());
            newur.setDirection(-1);
            // 要扣减原始的金额
            newur.setAmount(new BigDecimal(mlsuser.getAllProfit() - amountSrc.intValue()));
            newur.setBankCard(loginUser.getBankCard());
            newur.setRealName(name);
            newur.setIdCard(loginUser.getIdCard());
            newur.setMobile(loginUser.getMobile());
            userRecordSer.save(newur);

            //更新余额
            mlsuser.setTodaySales(0);
            mlsuser.setGetProfit(-amountSrc.intValue());
            mlsuser.setGetActivityProfit(0);
            mlsUserSer.updateMoney(mlsuser);

            return toResponsObject(0, "提现成功", null);
        }catch(Exception e){
            log.error("提现异常", e);
        }finally {
            RedisUtils.del("tx"+mlsuser.getMlsUserId());
        }

        return toResponsFail("提现失败，请联系联系管理员");
    }

    @ApiOperation(value = "用户活动余额提现")
    @PostMapping("withdrawCashesActivity")
    public Object withdrawCashesActivity(@LoginUser UserVo loginUser, @RequestParam("amount") Double amount) {
        String name = loginUser.getRealName();
        if(StringUtils.isBlank(name)) {
            return toResponsFail("真实姓名为空");
        }
        if(amount == null || amount == 0) {
            return toResponsFail("提现金额为空");
        }

        MlsUserEntity2 mlsuser = mlsUserSer.getEntityMapper().findByUserId(loginUser.getUserId());
        //系统设置的最小提现金额
        String txMin = mlsUserSer.getEntityMapper().queryByKey("tx_min");
        if(StringUtils.isNotBlank(txMin)) {
            int min = new Integer(txMin);
            if(min > amount) {
                return toResponsFail("最小提现金额为"+min);
            }
        }

        if(mlsuser.getGetProfit().intValue() < new Double(amount).intValue()) {
            return toResponsFail("超出活动余额");
        }

        //设置提现redis锁，当成功删除key
        String txKey = RedisUtils.get("txActivity"+mlsuser.getMlsUserId());
        if(StringUtils.isNotBlank(txKey)) {
            return toResponsFail("当前活动余额提现没有完成，也可以联系管理员。");
        }
        try{
            //设置redisKsy
            RedisUtils.set("txActivity"+mlsuser.getMlsUserId(), "10");

            //插入提现记录表
            UserRecordActivity newur = new UserRecordActivity();
            newur.setMlsUserId(mlsuser.getMlsUserId());
            newur.setTypes(4);
            newur.setTypesStr("提现");
            newur.setPrice(amount.intValue());
            newur.setRemarks("当前活动余额：" +mlsuser.getGetProfit().intValue()+ ",提现金额:"+amount.intValue());
            newur.setDirection(-1);
            // 要扣减原始的金额
            newur.setAmount(new BigDecimal(mlsuser.getGetProfit() - amount.intValue()));
            newur.setBankCard(loginUser.getBankCard());
            newur.setRealName(name);
            newur.setIdCard(loginUser.getIdCard());
            newur.setMobile(loginUser.getMobile());
            userRecordActivitySer.save(newur);

            //更新活动余额
            mlsuser.setTodaySales(0);
            mlsuser.setGetProfit(0);
            mlsuser.setGetActivityProfit(- amount.intValue());
            mlsUserSer.updateMoney(mlsuser);

            return toResponsObject(0, "提现成功", null);
        }catch(Exception e){
            log.error("提现异常", e);
        }finally {
            RedisUtils.del("txActivity"+mlsuser.getMlsUserId());
        }

        return toResponsFail("提现失败，请联系联系管理员");
    }

    //----------------------------------------------------

    /**
     * 增加分润记录
     * @param mlsUserId
     * @param price
     */
    private void addUserRecord(Long mlsUserId, int price, Long fxuser, int order_price, int orderId, String remark) {
        String remarks = remark +":"+fxuser+"给:"+mlsUserId+"分润，金额："+price;
        log.warn("fx==>"+remarks);
        MlsUserEntity2 mlsUser = mlsUserSer.getEntityMapper().getById(mlsUserId);

        UserRecord ur = new UserRecord();
        ur.setMlsUserId(mlsUserId);
        ur.setTypes(2);
        ur.setTypesStr("分润");
        ur.setPrice(price);
        ur.setRemarks(remarks);
        ur.setOrderId(orderId);
        ur.setDirection(1);//收入
        ur.setAmount(new BigDecimal(mlsUser.getAllProfit() + price));
        userRecordSer.save(ur);

        MlsUserEntity2 mlsUserVo= new MlsUserEntity2();
        mlsUserVo.setMlsUserId(mlsUserId);
        mlsUserVo.setTodaySales(order_price);
        mlsUserVo.setGetProfit(price);
        mlsUserSer.updateMoney(mlsUserVo);
    }


    private void sendCode(String mobile) {
        String random = CharUtil.getRandomNum(6);
        try {
            sendSms.send(mobile, random);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        RedisUtils.set("sms" + mobile, random, 60 * 5);
    }

    private Boolean verificationCode(String mobile, String verificationCode) {
        if (StringUtils.isBlank(verificationCode)) {
            return false;
        }
        if("local".equals(env)){
            if ("333333".equals(verificationCode)) {
                return true;
            }
        }
        String code = RedisUtils.get("sms" + mobile);
        return verificationCode.equals(code);
    }

    //=============================================================================================
    //=============================================================================================
    //=============================================================================================
    //--------------------------------------分润逻辑-------------------------------------------------

    /**
     * 计算分润
     * @param userId	Id
     * @param orderPrice	订单金额
     * @param orderId		订单ID
     */
    @ApiOperation(value = "计算分润")
    @GetMapping(value = "/fx")
    @IgnoreAuth
    public Object fx(@RequestParam("userId") Long userId, @RequestParam("orderPrice") BigDecimal orderPrice, @RequestParam("orderId") Integer orderId) {
        // 当前用户
        Pair<UserVo, MlsUserEntity2> curUser = this.getUserObject(userId);
        if(curUser == null){
            return toResponsFail("不存在该会员,userId" + userId);
        }

        Map<String, Object> params = new HashMap<>();
        params.put("order_id", orderId);
        List<OrderGoodsVo> orderGoodsVoList = apiOrderGoodsMapper.queryList(params);
        if (CollectionUtils.isEmpty(orderGoodsVoList)) {
            return toResponsFail("无效订单id,orderId" + orderId);
        }

        log.warn("fx==>"+curUser.getKey().getNickname() +"购买商品，级别："+ApiUserUtils.getLevelName(curUser.getKey().getUser_level_id())+"，订单号："+orderId+"，订单金额："+orderPrice);
        log.warn("fx==>开始...");

        if (ApiConstant.RETAIL_USER == curUser.getKey().getUser_level_id()) {// 游客购买
            log.warn("fx==>游客购买，判断是否要升级VIP!");
            // 获取游客历史的订单
            Map<String, Object> orderParams = new HashMap<>();
            orderParams.put("user_id", curUser.getKey().getUserId());
            List<OrderVo> orderVoList = orderService.queryList(orderParams);
            BigDecimal dbAllPrice = orderVoList.stream().map(OrderVo::getOrder_price).reduce(BigDecimal.ZERO, BigDecimal::add);
            int allPrice = dbAllPrice.intValue();
            log.warn("fx==>游客累计消费金额："+allPrice);
            if(allPrice >= 396){
                // 升级成VIP
                log.warn("fx==>"+curUser.getKey().getNickname()+"升级成VIP");
                UserVo userVo = new UserVo();
                userVo.setUserId(curUser.getKey().getUserId());
                userVo.setUser_level_id(ApiConstant.VIP_USER);
                userService.update(userVo);
            }
        }

        // 当前用户的推荐人
        Pair<UserVo, MlsUserEntity2> promoterOfCurUser = this.getUserObject(curUser.getKey().getPromoterId());
        if(promoterOfCurUser != null){
            log.warn("fx==>"+curUser.getKey().getNickname()+"的推荐人是："+promoterOfCurUser.getKey().getNickname()+"，推荐人等级："+ApiUserUtils.getLevelName(promoterOfCurUser.getKey().getUser_level_id()));
        }

        // 当前用户的上级
        Pair<UserVo, MlsUserEntity2> fidOfCurUser = this.getFidUserObject(curUser.getValue().getFid());

        Map<String, Object> couponParams = new HashMap<>();
        couponParams.put("order_id", orderId);
        couponParams.put("coupon_status", 2);
        couponParams.put("coupon_id", 30); // 活动现金券
        List<UserCouponVo>  userCouponVoList = userCouponService.queryList(couponParams);
        // 该笔订单使用了活动现金券，不需要分销
        if(CollectionUtils.isNotEmpty(userCouponVoList) && userCouponVoList.size() > 0){
            log.warn("fx==>该笔订单使用了活动现金券，不需要分销orderId="+orderId+"，活动现金券个数="+userCouponVoList.size());
        }else{
            // 计算每个产品的分润
            for (OrderGoodsVo orderGoodsVo : orderGoodsVoList) {
                GoodsVo goodsVo = goodsService.queryObject(orderGoodsVo.getGoods_id());
                // 非活动商品才参与分销
                if(!goodsVo.getIs_secKill().equals(5)){
                    log.warn("fx==>分销的商品："+goodsVo.getName()+"，购买数量："+orderGoodsVo.getNumber());

                    if (ApiConstant.RETAIL_USER == curUser.getKey().getUser_level_id()) {// 游客首次购买
                        log.warn("fx==>游客首次购买!");
                        retailBuyFx(orderPrice, orderId, curUser, promoterOfCurUser, fidOfCurUser, orderGoodsVo, goodsVo);
                    } else if (ApiConstant.VIP_USER == curUser.getKey().getUser_level_id()) {// VIP复购
                        log.warn("fx==>VIP复购!");
                        vipBuyFx(orderPrice, orderId, curUser, promoterOfCurUser, fidOfCurUser, orderGoodsVo, goodsVo);
                    } else {// 代理购买
                        log.warn("fx==>代理购买!");
                        proxyBuyFx(orderPrice, orderId, curUser, promoterOfCurUser, fidOfCurUser, orderGoodsVo, goodsVo);
                    }
                }else{
                    log.warn("fx==>该商品是活动商品，不参与分销："+goodsVo.getName()+"，购买数量："+orderGoodsVo.getNumber());
                }
            }
        }
        log.warn("fx==>结束！！！");
        return toResponsSuccess("分润完成");
    }


    private void retailBuyFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> curUser, Pair<UserVo, MlsUserEntity2> promoterOfcurUser, Pair<UserVo, MlsUserEntity2> fidOfcurUser, OrderGoodsVo orderGoodsVo, GoodsVo goodsVo) {
        // 是否要给vip推荐人分润, 现金券
        boolean isVipFx = false, isVipCouponFx = false;
        // 计算给VIP的分润
        BigDecimal vipPrice = goodsVo.getRetail_price().subtract(goodsVo.getVip_price()).multiply(new BigDecimal(orderGoodsVo.getNumber()));
        // 现金券金额
        BigDecimal couponAmount = goodsVo.getCoupon_amount().multiply(new BigDecimal(orderGoodsVo.getNumber()));
        // 同级培育奖
        BigDecimal price = goodsVo.getLevel_amount().multiply(new BigDecimal(orderGoodsVo.getNumber()));

        // 1. 游客首次购买，他的推荐人是VIP,要给分润，并且还有现金券
        if (promoterOfcurUser != null && promoterOfcurUser.getKey().getUser_level_id() == ApiConstant.VIP_USER) {
            log.warn("fx==>游客购买，他推荐人是VIP,要给分润，并且还有现金券");
            // 给VIP推荐人分润
            addUserRecord(promoterOfcurUser.getValue().getMlsUserId(), vipPrice.intValue(), curUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for vip promoter");
            isVipFx = true;

            // 套餐商品
            if(goodsVo.getIs_secKill().equals(4)){
                // 给VIP推荐人现金券分润
                addUserRecord(promoterOfcurUser.getValue().getMlsUserId(), couponAmount.intValue(), curUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for vip promoter cash");
                log.warn("fx==>套餐商品，直接发现金："+couponAmount);
            }else{
                // 给VIP推荐人现金券
                UserCouponVo userCouponVo = new UserCouponVo();
                userCouponVo.setCoupon_id(9);
                userCouponVo.setUser_id(promoterOfcurUser.getKey().getUserId());
                userCouponVo.setAdd_time(new Date());
                userCouponVo.setCoupon_price(couponAmount);
                userCouponVo.setMerchantId(ApiConstant.DEFAULT_MERCHANT_ID);
                userCouponVo.setCoupon_number(CharUtil.getRandomString(12));
                userCouponVo.setOrder_id(orderId);
                userCouponService.save(userCouponVo);
                log.warn("fx==>现金券金额："+couponAmount);
            }

            isVipCouponFx = true;
        }
        if(fidOfcurUser != null && fidOfcurUser.getKey().getUser_level_id() > 2){//上级有代理身份，进行分润
            if (ApiConstant.SHOP_USER.equals(fidOfcurUser.getKey().getUser_level_id())) { // 门店
                log.warn("fx==>游客的直接上级是门店："+fidOfcurUser.getKey().getNickname());
                this.shopFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, isVipFx, isVipCouponFx, vipPrice, couponAmount, price);
            } else if (ApiConstant.AGENT_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 总代
                log.warn("fx==>游客没有直接上级，他的上级是总代："+fidOfcurUser.getKey().getNickname());
                this.agentFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, isVipFx, isVipCouponFx, false, vipPrice, couponAmount, price);
            } else if (ApiConstant.REGION_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 大区
                log.warn("fx==>游客没有直接上级，他的上级是大区："+fidOfcurUser.getKey().getNickname());
                this.regionFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, isVipFx, isVipCouponFx, false, vipPrice, couponAmount, price);
            }else if (ApiConstant.COOP_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 战略
                log.warn("fx==>游客没有直接上级，他的上级是战略："+fidOfcurUser.getKey().getNickname());
                this.coopFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, isVipFx, isVipCouponFx, false, vipPrice, couponAmount, price);
            }
        }
    }


    private void vipBuyFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> curUser, Pair<UserVo, MlsUserEntity2> promoterOfcurUser, Pair<UserVo, MlsUserEntity2> fidOfcurUser, OrderGoodsVo orderGoodsVo, GoodsVo goodsVo) {
        // 是否要给vip推荐人现金券
        boolean isVipCouponFx = false;
        // 现金券金额
        BigDecimal couponAmount = goodsVo.getCoupon_amount().multiply(new BigDecimal(orderGoodsVo.getNumber()));
        // 同级培育奖
        BigDecimal price = goodsVo.getLevel_amount().multiply(new BigDecimal(orderGoodsVo.getNumber()));

        // VIP复购，他的推荐人是VIP,只能获得现金券
        if (promoterOfcurUser != null && ApiConstant.VIP_USER.equals(promoterOfcurUser.getKey().getUser_level_id())) {

            // 套餐商品
            if(goodsVo.getIs_secKill().equals(4)){
                // 给VIP推荐人现金券分润
                addUserRecord(promoterOfcurUser.getValue().getMlsUserId(), couponAmount.intValue(), curUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for vip promoter cash");
                log.warn("fx==>VIP复购，套餐商品，直接发现金："+couponAmount);
            }else{
                // 给推荐人现金券
                UserCouponVo userCouponVo = new UserCouponVo();
                userCouponVo.setCoupon_id(9);
                userCouponVo.setUser_id(promoterOfcurUser.getKey().getUserId());
                userCouponVo.setAdd_time(new Date());
                userCouponVo.setCoupon_price(couponAmount);
                userCouponVo.setMerchantId(ApiConstant.DEFAULT_MERCHANT_ID);
                userCouponVo.setCoupon_number(CharUtil.getRandomString(12));
                userCouponVo.setOrder_id(orderId);
                userCouponService.save(userCouponVo);

                log.warn("fx==>VIP复购，他的推荐人是VIP,只能获得现金券，现金券金额："+couponAmount);
            }
            isVipCouponFx = true;
        }
        if(fidOfcurUser != null && fidOfcurUser.getKey().getUser_level_id() > 2){//上级有代理身份，进行分润
            if (ApiConstant.SHOP_USER.equals(fidOfcurUser.getKey().getUser_level_id())) { // 门店
                log.warn("fx==>VIP的直接上级是门店："+fidOfcurUser.getKey().getNickname());
                this.shopFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, false, isVipCouponFx, null, couponAmount, price);
            } else if (ApiConstant.AGENT_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 总代
                log.warn("fx==>VIP没有直接上级，他的上级是总代："+fidOfcurUser.getKey().getNickname());
                this.agentFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, false, isVipCouponFx, false, null, couponAmount, price);
            } else if (ApiConstant.REGION_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 大区
                log.warn("fx==>VIP没有直接上级，他的上级是大区："+fidOfcurUser.getKey().getNickname());
                this.regionFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, false, isVipCouponFx, false, null, couponAmount, price);
            }else if (ApiConstant.COOP_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 战略
                log.warn("fx==>VIP没有直接上级，他的上级是战略："+fidOfcurUser.getKey().getNickname());
                this.coopFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, false, isVipCouponFx, false, null, couponAmount, price);
            }
        }
    }

    private void proxyBuyFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> curUser, Pair<UserVo, MlsUserEntity2> promoterOfcurUser, Pair<UserVo, MlsUserEntity2> fidOfcurUser, OrderGoodsVo orderGoodsVo, GoodsVo goodsVo) {
        log.warn("fx==>代理购买，先给他的推荐人分润");
        // 同级培育奖
        BigDecimal price = goodsVo.getLevel_amount().multiply(new BigDecimal(orderGoodsVo.getNumber()));

        // 给当前代理用户的推荐人分润， 是否分润成功
        boolean isPromoterFx = this.forProxyPromoterFx(orderPrice, orderId, curUser, curUser, price);

        if(fidOfcurUser != null){
            if (ApiConstant.AGENT_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 总代
                log.warn("fx==>该代理的直接上级是总代："+fidOfcurUser.getKey().getNickname());
                this.agentFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);
            } else if (ApiConstant.REGION_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 大区
                log.warn("fx==>该代理没有直接上级，他的上级是大区："+fidOfcurUser.getKey().getNickname());
                this.regionFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);
            }else if (ApiConstant.COOP_USER.equals(fidOfcurUser.getKey().getUser_level_id())) {// 战略
                log.warn("fx==>该代理没有直接上级，他的上级是战略："+fidOfcurUser.getKey().getNickname());
                this.coopFx(orderPrice, orderId, curUser, curUser, fidOfcurUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);
            }
        }else{
            log.warn("fx==>该代理是最高级别战略，不用向上级分润");
        }
    }

    private void coopFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> preUser, Pair<UserVo, MlsUserEntity2> curUser, Pair<UserVo, MlsUserEntity2> proxyUser, OrderGoodsVo orderGoodsVo, GoodsVo goodsVo, boolean isVipFx, boolean isVipCouponFx, boolean isPromoterFx, BigDecimal vipPrice, BigDecimal couponAmount, BigDecimal price) {
        log.warn("fx==>给战略"+proxyUser.getKey().getNickname()+"分润...");

        // 默认游客零售价购买
        BigDecimal startPrice = goodsVo.getRetail_price();
        if(ApiConstant.VIP_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getVip_price();
        }else if(ApiConstant.SHOP_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getShop_price();
        }else if(ApiConstant.AGENT_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getAgent_price();
        }else if(ApiConstant.REGION_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getRegion_price();
        }

        // 给战略分润
        BigDecimal coopPrice = startPrice
                .subtract(goodsVo.getCoop_price())
                .multiply(new BigDecimal(orderGoodsVo.getNumber()))
                .subtract(isPromoterFx ? price : BigDecimal.ZERO)
                .subtract(isVipFx ? vipPrice : BigDecimal.ZERO)
                .subtract(isVipCouponFx ? couponAmount : BigDecimal.ZERO);
        addUserRecord(proxyUser.getValue().getMlsUserId(), coopPrice.intValue(), curUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for coop");
        // 给战略推荐人， 是否分润成功
        this.forProxyPromoterFx(orderPrice, orderId, proxyUser, curUser, price);
    }

    private void regionFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> preUser, Pair<UserVo, MlsUserEntity2> curUser, Pair<UserVo, MlsUserEntity2> proxyUser, OrderGoodsVo orderGoodsVo, GoodsVo goodsVo, boolean isVipFx, boolean isVipCouponFx, boolean isPromoterFx, BigDecimal vipPrice, BigDecimal couponAmount, BigDecimal price) {
        log.warn("fx==>从大区"+proxyUser.getKey().getNickname()+"开始分润...");

        // 默认游客零售价购买
        BigDecimal startPrice = goodsVo.getRetail_price();
        if(ApiConstant.VIP_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getVip_price();
        }else if(ApiConstant.SHOP_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getShop_price();
        }else if(ApiConstant.AGENT_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getAgent_price();
        }

        // 给大区分润
        BigDecimal regionPrice = startPrice
                .subtract(goodsVo.getRegion_price())
                .multiply(new BigDecimal(orderGoodsVo.getNumber()))
                .subtract(isPromoterFx ? price : BigDecimal.ZERO)
                .subtract(isVipFx ? vipPrice : BigDecimal.ZERO)
                .subtract(isVipCouponFx ? couponAmount : BigDecimal.ZERO);
        addUserRecord(proxyUser.getValue().getMlsUserId(), regionPrice.intValue(), curUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for region");

        // 给大区推荐人， 是否分润成功
        isPromoterFx = this.forProxyPromoterFx(orderPrice, orderId, proxyUser, curUser, price);

        // 代理用户的上级
        Pair<UserVo, MlsUserEntity2> fidOfProxyUser = this.getFidUserObject(proxyUser.getValue().getFid());

        // 只可能是战略
        if(fidOfProxyUser != null && ApiConstant.COOP_USER.equals(fidOfProxyUser.getKey().getUser_level_id())){
            log.warn("fx==>大区："+proxyUser.getKey().getNickname()+"的直接上级是战略："+fidOfProxyUser.getKey().getNickname());
            this.coopFx(orderPrice, orderId, proxyUser, curUser, fidOfProxyUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);

        }
    }

    private void agentFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> preUser, Pair<UserVo, MlsUserEntity2> curUser, Pair<UserVo, MlsUserEntity2> proxyUser, OrderGoodsVo orderGoodsVo, GoodsVo goodsVo, boolean isVipFx, boolean isVipCouponFx, boolean isPromoterFx, BigDecimal vipPrice, BigDecimal couponAmount, BigDecimal price) {
        log.warn("fx==>从总代"+proxyUser.getKey().getNickname()+"开始分润...");

        // 默认游客零售价购买
        BigDecimal startPrice = goodsVo.getRetail_price();
        if(ApiConstant.VIP_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getVip_price();
        }else if(ApiConstant.SHOP_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getShop_price();
        }

        // 给总代分润
        BigDecimal agentPrice = startPrice
                .subtract(goodsVo.getAgent_price())
                .multiply(new BigDecimal(orderGoodsVo.getNumber()))
                .subtract(isPromoterFx ? price : BigDecimal.ZERO)
                .subtract(isVipFx ? vipPrice : BigDecimal.ZERO)
                .subtract(isVipCouponFx ? couponAmount : BigDecimal.ZERO);
        addUserRecord(proxyUser.getValue().getMlsUserId(), agentPrice.intValue(), curUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for agent");

        // 给总代推荐人， 是否分润成功
        isPromoterFx = this.forProxyPromoterFx(orderPrice, orderId, proxyUser, curUser, price);

        // 代理用户的上级
        Pair<UserVo, MlsUserEntity2> fidOfProxyUser = this.getFidUserObject(proxyUser.getValue().getFid());

        if(fidOfProxyUser != null){
            if (ApiConstant.REGION_USER.equals(fidOfProxyUser.getKey().getUser_level_id())) {// 大区
                log.warn("fx==>总代："+proxyUser.getKey().getNickname()+"的直接上级是大区："+fidOfProxyUser.getKey().getNickname());
                this.regionFx(orderPrice, orderId, proxyUser, curUser, fidOfProxyUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);

            }else if(ApiConstant.COOP_USER.equals(fidOfProxyUser.getKey().getUser_level_id())){// 战略
                log.warn("fx==>总代："+proxyUser.getKey().getNickname()+"没有直接上级， 他的上级是战略："+fidOfProxyUser.getKey().getNickname());
                this.coopFx(orderPrice, orderId, proxyUser, curUser, fidOfProxyUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);
            }
        }
    }

    /**
     * 只有游客购买或者VIP复购才会进入该方法
     * 门店分润
     * @param orderPrice
     * @param orderId
     * @param curUser
     * @param proxyUser
     * @param orderGoodsVo
     * @param goodsVo
     * @param isVipFx
     */
    private void shopFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> preUser, Pair<UserVo, MlsUserEntity2> curUser, Pair<UserVo, MlsUserEntity2> proxyUser, OrderGoodsVo orderGoodsVo, GoodsVo goodsVo, boolean isVipFx, boolean isVipCouponFx, BigDecimal vipPrice, BigDecimal couponAmount, BigDecimal price) {
        log.warn("fx==>从门店"+proxyUser.getKey().getNickname()+"开始分润...");
        // 默认游客零售价购买
        BigDecimal startPrice = goodsVo.getRetail_price();
        if(ApiConstant.VIP_USER.equals(preUser.getKey().getUser_level_id())){
            startPrice = goodsVo.getVip_price();
        }

        // 给门店分润
        BigDecimal shopPrice = startPrice
                .subtract(goodsVo.getShop_price())
                .multiply(new BigDecimal(orderGoodsVo.getNumber()))
                .subtract(isVipFx ? vipPrice : BigDecimal.ZERO)
                .subtract(isVipCouponFx ? couponAmount : BigDecimal.ZERO);
        addUserRecord(proxyUser.getValue().getMlsUserId(), shopPrice.intValue(), curUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for shop");

        // 给门店推荐人， 是否分润成功
        boolean isPromoterFx = this.forProxyPromoterFx(orderPrice, orderId, proxyUser, curUser, price);

        // 代理用户的上级
        Pair<UserVo, MlsUserEntity2> fidOfProxyUser = this.getFidUserObject(proxyUser.getValue().getFid());

        if(fidOfProxyUser != null){
            if (ApiConstant.AGENT_USER.equals(fidOfProxyUser.getKey().getUser_level_id())) {// 总代
                log.warn("fx==>门店："+proxyUser.getKey().getNickname()+"的直接上级是总代："+fidOfProxyUser.getKey().getNickname());
                this.agentFx(orderPrice, orderId, proxyUser, curUser, fidOfProxyUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);
            }else if(ApiConstant.REGION_USER == fidOfProxyUser.getKey().getUser_level_id()){// 大区
                log.warn("fx==>门店："+proxyUser.getKey().getNickname()+"没直接上级，上级是大区："+fidOfProxyUser.getKey().getNickname());
                this.regionFx(orderPrice, orderId, proxyUser, curUser, fidOfProxyUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);
            }else if(ApiConstant.COOP_USER == fidOfProxyUser.getKey().getUser_level_id()){// 战略
                log.warn("fx==>门店："+proxyUser.getKey().getNickname()+"没有直接上级， 他的上级是战略："+fidOfProxyUser.getKey().getNickname());
                this.coopFx(orderPrice, orderId, proxyUser, curUser, fidOfProxyUser, orderGoodsVo, goodsVo, false, false, isPromoterFx, null, null, price);
            }
        }
    }



    /**
     * 根据用户id获取用户对象
     * @param userId
     * @return
     */
    private Pair<UserVo, MlsUserEntity2> getUserObject(Long userId){
        UserVo userVo = null;
        MlsUserEntity2 fxUser = null;
        if (userId != null && userId > 0) {
            // 用户信息
            userVo = userService.queryObject(userId);
            if(userVo != null){
                // 对应的分销用户信息
                fxUser = mlsUserSer.getEntityMapper().findByUserId(userVo.getUserId());

                return new Pair<>(userVo, fxUser);
            }
        }
        return null;
    }

    /**
     * 根据分销用户的fid获取上级用户对象
     * @param fid
     * @return
     */
    private Pair<UserVo, MlsUserEntity2> getFidUserObject(Long fid){
        UserVo userVo = null;
        MlsUserEntity2 fxUser = null;
        if (fid != null && fid > 0) {
            fxUser = mlsUserSer.getEntityMapper().getById(fid);
            userVo = userService.queryObject(fxUser.getUserId());
            return new Pair<>(userVo, fxUser);
        }
        return null;
    }

    private boolean forProxyPromoterFx(BigDecimal orderPrice, Integer orderId, Pair<UserVo, MlsUserEntity2> curProxyUser, Pair<UserVo, MlsUserEntity2> buyUser, BigDecimal price){
        // 代理用户的推荐人
        Pair<UserVo, MlsUserEntity2> promoterOfCurProxyUser = this.getUserObject(curProxyUser.getKey().getPromoterId());
        if(promoterOfCurProxyUser != null){
            String promoterLevelName = ApiUserUtils.getLevelName(promoterOfCurProxyUser.getKey().getUser_level_id());
            log.warn("fx==>" + ApiUserUtils.getLevelName(curProxyUser.getKey().getUser_level_id()) + ":" + curProxyUser.getKey().getNickname()+"的推荐人是："+promoterOfCurProxyUser.getKey().getNickname()+"，推荐人等级："+ promoterLevelName);
            // 推荐人的级别和他一样，则获取同级培育奖
            if (promoterOfCurProxyUser.getKey().getUser_level_id() == curProxyUser.getKey().getUser_level_id()) {
                // 给推荐人分润
                addUserRecord(promoterOfCurProxyUser.getValue().getMlsUserId(), price.intValue(), buyUser.getValue().getMlsUserId(), orderPrice.intValue(), orderId, "for "+promoterLevelName+" promoter");
                return true;
            }
        }
        return false;
    }


    //---------------------------------------------分润逻辑 end-------------------------------------------

    /**
     * 订单退款请求
     */
    @ApiOperation(value = "订单退款请求")
    @PostMapping("refund")
    public Object refund(@RequestParam("orderId") Integer orderId) {
        OrderVo orderInfo = orderService.queryObject(orderId);

        if (null == orderInfo) {
            return toResponsObject(400, "订单已取消", "");
        }

        if (orderInfo.getPay_status() != 2) {
            return toResponsObject(400, "订单未付款，不能退款", "");
        }

        if (orderInfo.getOrder_status() == 4) {
            return toResponsObject(400, "订单已完成，不能退款", "");
        }
        if (orderInfo.getOrder_status() == 5) {
            return toResponsObject(400, "订单已退款，不能重复退款", "");
        }

		WechatRefundApiResult result = WechatUtil.wxRefund(orderInfo.getAll_order_id().toString(),
				orderInfo.getAll_price().doubleValue(), orderInfo.getAll_price().doubleValue());
        if (result.getResult_code().equals("SUCCESS")) {
            //修改订单状态
            OrderVo neworderInfo = new OrderVo();
            neworderInfo.setAll_order_id(orderInfo.getAll_order_id());
            neworderInfo.setOrder_status(5);// 已退款
            orderService.updateStatus(orderInfo);

            return toResponsObject(0, "成功退款", "");
        } else {
            return toResponsObject(400, "退款失败", "");
        }
    }


}

